通过文件头判断图片类型

Opencv加载一幅图片的时候只看图片实际的图片格式,与后缀名无关;所以如果一幅图片实际是Opencv支持的图片格式,即使后缀名是txt也没关系。

但如果某个文件打着jpg的后缀名,但实际却是其他乱七八糟的格式,那么如果不加判断的cvLoadImage一幅“图片”,可能就会出错。出错的原因有:1.文件虽然是jpg等图片后缀,但实际不是图片,或者不是Opencv支持的图片----如gif;2.图片不完整(这种情况在读入之前是无法判断的,所以只好用try catch来解决了)。所以在load一幅图片之前最好添加一个判断操作。

.Net里有现成的类可以进行这个判断,如:

 

System::Drawing::Image^ img_valid = System::Drawing::Image::FromFile("图片路径");//由文件创建一个Image类变量
if(img_valid->RawFormat->Equals(System::Drawing::Imaging::ImageFormat::Jpeg)||img_valid->RawFormat->Equals(System::Drawing::Imaging::ImageFormat::Bmp)
||img_valid->RawFormat->Equals(System::Drawing::Imaging::ImageFormat::Png))


这里首先由文件路径创建一个Image类,然后判断其实际类型。大部分情况下这是可行的,但如果一个网页文件被修改了后缀名为.jpg,由它来创建一个Image类就会报错!

所以这里我自己写了一个读文件头几个自己来判断是否是图片的函数。首先介绍一下图片文件头表示图片类型的部分:

1.JPEG
- 文件头标识 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件标识)
- 文件结束标识 (2 bytes): 0xff, 0xd9 (EOI)

2.TGA
- 未压缩的前5字节 00 00 02 00 00
- RLE压缩的前5字节 00 00 10 00 00

3.PNG
- 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A

4.GIF
- 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
G I F 8 9 (7) a

5.BMP
- 文件头标识 (2 bytes) 42 4D
B M

6.PCX
- 文件头标识 (1 bytes) 0A

7.TIFF
- 文件头标识 (2 bytes) 4D 4D 或 49 49

8.ICO
- 文件头标识 (8 bytes) 00 00 01 00 01 00 20 20

9.CUR
- 文件头标识 (8 bytes) 00 00 02 00 01 00 20 20

10.IFF
- 文件头标识 (4 bytes) 46 4F 52 4D
F O R M

11.ANI
- 文件头标识 (4 bytes) 52 49 46 46
R I F F

对于图片的文件头,大家可以用winhex打开一幅图片就可以看到前面的几个字节。下面是读文件头8个字节然后判断图片类型的函数,因为这里我只需要jpeg/bmp/png格式的,所以其他格式的即使是图片也归到nothing里面。

enum ImageType{
	jpg,
	bmp,
	png,
	nothing
};
ImageType image_type(const char* path)
{
	ifstream inFile(path);
	uchar png_type[9] = {0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,'/0'};
	uchar file_head[9];
	for (int i=0;i<8;++i)
	{
		inFile>>file_head[i];
	}
	file_head[8] = '/0';
	switch (file_head[0])
	{
	case 0xff:
		if (file_head[1]==0xd8)
			return jpg;//jpeg
	case 0x42:
		if (file_head[1]==0x4D)
			return bmp;//bmp
	case 0x89:
		if (file_head[1]==png_type[1] && file_head[2]==png_type[2] && file_head[3]==png_type[3] && file_head[4]==png_type[4]&&
			file_head[5]==png_type[5] && file_head[6]==png_type[6] && file_head[7]==png_type[7])
			return png;//png
	default:
		return nothing;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值