加载JPEG时出错:“GDI +中发生了一般错误。”

时间:2009-07-17 15:10:04

标签: c# image gdi+

我有一些JPEG文件似乎无法加载到我的C#应用​​程序中。它们可以很好地加载到其他应用程序中,例如GIMP。这是我用来加载图像的代码行:

System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\Image.jpg");

我得到的例外是:“GDI +中发生了一般错误。”,这真的不是很有用。有没有其他人遇到这个,或知道解决方法?

注意:如果您想测试问题,可以使用download a test image在C#中无效。

5 个答案:

答案 0 :(得分:5)

这个问题有一个确切的答案。我们今天遇到了这个问题,我能够最终证明这里发生了什么。

JPEG标准定义了一种元数据格式,一种由一系列“数据块”(称为“段”)组成的文件。每个块以FF标记开始,然后是另一个标记字节,以标识它是什么类型的块,后跟一对描述块长度的字节(16位小端值)。一些块(如FFD8,“图像开始”)对文件的使用至关重要,有些(如FFFE,“注释”)完全没有意义。

当定义JPEG标准时,它们还包括所谓的“APP标记”---类型FFE0到FFEF ---它们应该用于“特定于应用程序的数据”。它们被各种程序以各种方式滥用,但在大多数情况下,它们没有意义,可以安全地忽略,除了用于JFIF数据的APP0(FFE0):JFIF略微扩展了JPEG标准包括其他有用的信息,如图像的DPI。

image的问题在于它包含一个FFE1标记,该标记后面有一个大小为零的块。这是一个不起眼的图像数据(一个非凡的图像,但不起眼的数据)除了那个奇怪的小无用的APP1块。 GDI +错误地试图解释那个APP1块,可能试图将其解码为EXIF数据,并且它正在爆炸。 (我的猜测是GDI +正在死亡,因为它试图实际处理一个零大小的数组。)如果GDI +写得正确,它会忽略任何它不理解的APPn块,而是试图理解它根据定义,数据是非标准的,它会迸发出火焰。

所以解决方法是编写一个小程序,将你的文件读入内存,去掉不需要的APPn块(标记FFE1到FFEF),然后将得到的“干净”图像数据输入GDI +,然后它正确处理。

我们目前正在进行一项正在进行的比赛,看看谁能以最快的速度编写JPEG清洁程序,并获得有趣的奖品: - )


对于反对者:该图像“略微不标准”。图像使用APP1用于其自身目的,并且GDI +尝试处理该数据是非常错误的。其他应用程序在读取图像时没有问题,因为它们正确地忽略了它们应该使用的APP块。

答案 1 :(得分:1)

.Net没有处理该特定图像的格式,可能是因为jpeg数据格式略有破坏或非标准。如果将图像加载到GIMP并保存到新文件,则可以使用Image类加载它。据推测,GIMP对文件格式问题有点宽容。

答案 2 :(得分:0)

thread from MSDN Forums可能有用。

  

错误可能意味着数据已损坏   或者有一些潜在的流   那太早了。

答案 3 :(得分:0)

错误可能是权限问题。特别是如果您的应用程序是ASP.NET应用程序。尝试将文件移动到与可执行文件相同的目录(如果是Win表单)或Web应用程序的根目录(如果是asp.net)。

答案 4 :(得分:0)

我有同样的问题。

我注意到的唯一区别是压缩。它适用于“JPEG”,但当压缩为“Progressive JPEG”时,我得到异常(GDI +中发生了一般错误)。

起初我认为这可能是一个内存问题,因为我提到的图像有点大(磁盘大约5MB,内存可能大约80MB),但后来我注意到压缩类型的差异。

当我在IrfanView或GIMP等其他程序中打开/保存图像文件时,结果还可以,但这不是主意。