确定图像的文件类型
我正在从服务中下载一些图像,这些图像并不总是包含内容类型,并且不提供我正在下载的文件的扩展名(哦,不要问)。
确定.NET中图像格式的最佳方法是什么?
正在读取这些下载的图像的应用程序需要具有适当的文件扩展名,否则所有地狱都将丢失。
解决方案
回答
尝试将流加载到System.IO.BinaryReader中。
然后,我们需要参考所需的每种图像格式的规范,并逐字节加载标头以与规范进行比较。例如,这是PNG规范
补充:PNG的实际文件结构。
回答
所有图像格式均将其初始字节设置为特定值:
- JPG:0xFF 0xD8
- PNG:0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
- GIF:" G"," I"," F"
搜索" jpg文件格式",将jpg替换为我们需要识别的其他文件格式。
正如Garth所建议的那样,有一个数据库可以显示许多文件的文件类型。如果我们必须检测很多不同的文件类型,则值得一看,以查找所需的信息。如果确实需要扩展它以涵盖许多文件类型,请查看相关的文件命令,该命令实现了引擎以正确使用数据库(对于许多文件格式而言,这并非易事,几乎是一个统计过程)
-亚当
回答
亚当指的是正确的方向。
如果我们想了解几乎所有文件的感知方法,请查看UNIX,Linux或者Mac OS X计算机上file
命令后面的数据库。
"文件"使用一个魔幻数字数据库,其中列出了Adam列出的初始字节,以检测文件的类型。 ``man file''会告诉我们在机器上的哪里找到数据库,例如/ usr / share / file / magic
。 man magic
会告诉你它的格式。
我们可以根据在数据库中看到的内容编写自己的检测代码,使用预先打包的库(例如python-magic),或者如果我们真的很喜欢实现.NET版本的libmagic
。我找不到一个,希望另一个成员可以指出一个。
如果我们没有方便的UNIX计算机,则数据库如下所示:
# PNG [Portable Network Graphics, or "PNG's Not GIF"] images # (Greg Roelofs, [email protected]) # (Albert Cahalan, [email protected]) # # 137 P N G \r \n ^Z \n [4-byte length] H E A D [HEAD data] [HEAD crc] ... # 0 string \x89PNG PNG image data, >4 belong !0x0d0a1a0a CORRUPTED, >4 belong 0x0d0a1a0a >>16 belong x %ld x >>20 belong x %ld, >>24 byte x %d-bit >>25 byte 0 grayscale, >>25 byte 2 \b/color RGB, >>25 byte 3 colormap, >>25 byte 4 gray+alpha, >>25 byte 6 \b/color RGBA, #>>26 byte 0 deflate/32K, >>28 byte 0 non-interlaced >>28 byte 1 interlaced 1 string PNG PNG image data, CORRUPTED # GIF 0 string GIF8 GIF image data >4 string 7a \b, version 8%s, >4 string 9a \b, version 8%s, >6 leshort >0 %hd x >8 leshort >0 %hd #>10 byte &0x80 color mapped, #>10 byte&0x07 =0x00 2 colors #>10 byte&0x07 =0x01 4 colors #>10 byte&0x07 =0x02 8 colors #>10 byte&0x07 =0x03 16 colors #>10 byte&0x07 =0x04 32 colors #>10 byte&0x07 =0x05 64 colors #>10 byte&0x07 =0x06 128 colors #>10 byte&0x07 =0x07 256 colors
祝你好运!
回答
可能更简单的方法是使用Image.FromFile()然后使用RawFormat属性,因为它已经知道最常见格式的标头中的魔术位,如下所示:
Image i = Image.FromFile("c:\foo"); if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat)) MessageBox.Show("JPEG"); else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat)) MessageBox.Show("GIF"); //Same for the rest of the formats