我有一些JPEG文件似乎无法加载到我的C#应用程序中。它们可以很好地加载到其他应用程序中,例如GIMP。这是我用来加载图像的代码行:
System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\Image.jpg");
我得到的例外是:“GDI +中发生了一般错误。”,这真的不是很有用。有没有其他人遇到这个,或知道解决方法?
注意:如果您想测试问题,可以使用download a test image在C#中无效。
答案 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等其他程序中打开/保存图像文件时,结果还可以,但这不是主意。