通常是通过文件后缀名查找图片文件,如果没有文件后缀的图片或者伪造的图片文件,则这种判定方法将达不到要求。我们可以根据读取文件头进行图片文件类型的判定。
比较流行的图片文件类型有: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 下测试例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h> int main(int argc, const char *argv[])
{
int ret = ;
DIR * dir;
struct dirent * info;
// int i=0; if(argc != ){
printf("Usage: %s /path/to/file",argv[]);
return -;
} dir = opendir(argv[]);
if(!dir){
perror("opendir");
return -;
} while((info = readdir(dir)) != NULL){
struct stat file_sta;
ret = stat(info->d_name,&file_sta);
if(ret < ){
perror("stat");
return -;
} if(S_ISREG(file_sta.st_mode)){
printf("%s \n",info->d_name);
FILE *fp = fopen(info->d_name,"rb");
if(!fp){
perror("fopen");
continue;
}
// 此处的类型定义必须定义为 unsigned 类型 (不然编译器会当做有符号类型处理)
unsigned char buf[] = {};
ret = fread(buf,,,fp); if((buf[] == 0x42) && (buf[] == 0x4D)){
printf("file type(bmp) : %s \n",info->d_name);
}
else if((buf[] == 0xFF) && (buf[] == 0xD8) && (buf[] == 0xFF)){
printf("file type(jpg) : %s \n",info->d_name);
}
else if((buf[] == 0x89) && (buf[] == 0x50) && (buf[] == 0x4e) && (buf[] == 0x47)){
printf("file type(png) : %s \n",info->d_name);
}
else if((buf[] == 0x47) && (buf[] == 0x49) && (buf[] == 0x46) && (buf[] == 0x38)){
printf("file type(gif) : %s \n",info->d_name);
}
else{ }
fclose(fp);
}
} closedir(dir); return ;
}
运行结果: