Archive for August, 2007

根据图片文件头判断图片类型

2007-8-10 20:57 | by 2ndboy

  发现很久没有写过技术话题啦,赶紧来写一篇:)

  近来项目中需要从拿到的各种图片数据中分辨出图片格式来,于是 Google 一番后小有所得,拿出来分享一下。

  先来说 PNG 格式,这里有 PNG 格式的规范文档,从文档里可以看到,所有 PNG 格式文件的前 8 个字节都是一样的,可以用这个来判断。以下代码都假设 pData 指向图片数据:

  1. if( 0 == memcmp( pData, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8 ) )

  JPEG 格式可以参考这个文档,文档里面有这样一句话“you can identify a JFIF file by looking for the following sequence: X’FF’, SOI, X’FF’,
APP0, <2 bytes to be skipped>, “JFIF”, X’00’”,所以可以这样判断:

  1. if( 0xFF == pData[0] && 0xFF == pData[2] && 0 == memcmp( &pData[6], "JFIF\x00", 5 ) )

  GIF 格式的文档可以看这里,GIF 文件的前 3 个字节都是“GIF”,接下来的 3 个字节是版本号,可能的版本号貌似只有两种“87a”和“89a”,所以可以这样判断数据是否是 GIF 格式:

  1. if( 0 == memcmp( pData, "GIF87a", 6 ) || 0 == memcmp( pData, "GIF89a", 6 ) )

  TIFF 格式的文档在这里,TIFF 文件的前两个字节不是“II”就是“MM”(美眉?),“II”代表 Intel 字节顺序,“MM”代表 Motorola 字节顺序(也就是网络字节顺序)。接下来的两个字节始终是“\x00\x2A”,所以可以这样来判断:

  1. if( ( 0 == memcmp( pData, "II", 2 ) || 0 == memcmp( pData, "MM", 2 ) ) && 0 == memcmp( &pData[2], "\x00\x2A", 2 ) )