linux 下查找图片文件方法
通常是通过文件后缀名查找图片文件,如果没有文件后缀的图片或者伪造的图片文件,则这种判定方法将达不到要求。我们可以根据读取文件头进行图片文件类型的判定。
比较流行的图片文件类型有:jpg png bmp gif 这几种,下面将介绍区分这几种图片的方式:
BMP (bmp) 文件头(2 byte): 0x42,0x4D
JPEG (jpg) 文件头(3 byte): 0xFF,0xD8,0xFF
PNG (png) 文件头(4 byte): 0x89,0x50,0x4E,0x47
GIF (gif) 文件头(4byte): 0x47,0x49,0x46,0x38
应用程序通过可以读取文件头进行匹配。linux 下测试例子:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <sys/types.h> 6 #include <sys/stat.h> 7 #include <dirent.h> 8 9 int main(int argc, const char *argv[]) 10 { 11 int ret = 0; 12 DIR * dir; 13 struct dirent * info; 14 // int i=0; 15 16 if(argc != 2){ 17 printf("Usage: %s /path/to/file",argv[0]); 18 return -1; 19 } 20 21 dir = opendir(argv[1]); 22 if(!dir){ 23 perror("opendir"); 24 return -1; 25 } 26 27 while((info = readdir(dir)) != NULL){ 28 struct stat file_sta; 29 ret = stat(info->d_name,&file_sta); 30 if(ret < 0){ 31 perror("stat"); 32 return -1; 33 } 34 35 if(S_ISREG(file_sta.st_mode)){ 36 printf("%s \n",info->d_name); 37 FILE *fp = fopen(info->d_name,"rb"); 38 if(!fp){ 39 perror("fopen"); 40 continue; 41 } 42 // 此处的类型定义必须定义为 unsigned 类型 (不然编译器会当做有符号类型处理) 43 unsigned char buf[4] = {0}; 44 ret = fread(buf,4,1,fp); 45 46 if((buf[0] == 0x42) && (buf[1] == 0x4D)){ 47 printf("file type(bmp) : %s \n",info->d_name); 48 } 49 else if((buf[0] == 0xFF) && (buf[1] == 0xD8) && (buf[2] == 0xFF)){ 50 printf("file type(jpg) : %s \n",info->d_name); 51 } 52 else if((buf[0] == 0x89) && (buf[1] == 0x50) && (buf[2] == 0x4e) && (buf[3] == 0x47)){ 53 printf("file type(png) : %s \n",info->d_name); 54 } 55 else if((buf[0] == 0x47) && (buf[1] == 0x49) && (buf[2] == 0x46) && (buf[3] == 0x38)){ 56 printf("file type(gif) : %s \n",info->d_name); 57 } 58 else{ 59 60 61 } 62 fclose(fp); 63 } 64 } 65 66 closedir(dir); 67 68 return 0; 69 }
运行结果: