通常是通過文件后綴名查找圖片文件,如果沒有文件后綴的圖片或者偽造的圖片文件,則這種判定方法將達不到要求。我們可以根據讀取文件頭進行圖片文件類型的判定。
比較流行的圖片文件類型有: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 }
運行結果: