我有一些JPEG文件似乎无法加载到我的C#应用程序中.它们可以很好地加载到其他应用程序中,例如GIMP.这是我用来加载图像的代码行:
System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\Image.jpg");
我得到的例外是:"GDI +中发生了一般错误.",这实际上不是很有帮助.有没有其他人遇到这个,或知道解决方法?
注意:如果您想测试该问题,可以下载在C#中不起作用的测试图像.
这个问题有一个确切的答案.我们今天遇到了这个问题,我能够最终证明这里发生了什么.
JPEG标准定义了元数据格式,该文件由一系列"数据块"(称为"段")组成.每个块以FF标记开始,然后是另一个标记字节,以标识它是什么类型的块,后跟一对描述块长度的字节(16位小端值).一些块(如FFD8,"图像开始")对文件的使用至关重要,而一些(如FFFE,"注释")完全没有意义.
当定义JPEG标准时,它们还包括所谓的"APP标记"---类型FFE0到FFEF ---它们应该用于"特定于应用程序的数据".它们被各种程序以各种方式滥用,但在大多数情况下,它们没有意义,可以安全地忽略,除了用于JFIF数据的APP0(FFE0):JFIF略微扩展了JPEG标准包括其他有用的信息,如图像的DPI.
图像的问题在于它包含一个FFE1标记,该标记后面有一个大小为零的块.这是一个不起眼的图像数据(一个非凡的图像,但不起眼的数据)除了那个奇怪的小无用的APP1块.GDI +错误地试图解释那个APP1块,可能试图将其解码为EXIF数据,并且它正在爆炸.(我的猜测是GDI +正在死亡,因为它试图实际处理一个零大小的数组.)如果GDI +写得正确,它将忽略任何它不理解的APPn块,而是试图理解它根据定义,非标准的数据,它会迸发出火焰.
因此,解决方案是编写一个将您的文件读入内存的小程序,去掉不需要的APPn块(标记FFE1到FFEF),然后将生成的"干净"图像数据输入GDI +,然后它将正确处理.
我们目前正在进行一项正在进行的比赛,看看谁能以最快的速度编写JPEG清洁程序,并获得有趣的奖品:-)
对于反对者:这种形象并非 "略微不规范".图像使用APP1用于其自身目的,并且GDI +尝试处理该数据是非常错误的.其他应用程序读取图像没有问题,因为它们正确地忽略了它们应该使用的APP块.