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

时间:2020-12-19 18:25:16

I have some JPEG files that I can't seem to load into my C# application. They load fine into other applications, like the GIMP. This is the line of code I'm using to load the image:

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

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

The exception I get is: "A generic error occurred in GDI+.", which really isn't very helpful. Has anyone else run into this, or know a way around it?

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

Note: If you would like to test the problem you can download a test image that doesn't work in C#.

注意:如果您想测试该问题,可以下载在C#中不起作用的测试图像。

5 个解决方案

#1


.Net isn't handling the format of that particular image, potentially because the jpeg data format is slightly broken or non-standard. If you load the image into GIMP and save to a new file you can then load it with the Image class. Presumably GIMP is a bit more forgiving of file format problems.

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

#2


There's an exact answer to this problem. We ran into this at work today, and I was able to prove conclusively what's going on here.

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

The JPEG standard defines a metadata format, a file that consists of a series of "chunks" of data (which they call "segments"). Each chunk starts with FF marker, followed by another marker byte to identify what kind of chunk it is, followed by a pair of bytes that describe the length of the chunk (a 16-bit little-endian value). Some chunks (like FFD8, "Start of Image") are critical to the file's usage, and some (like FFFE, "Comment") are utterly meaningless.

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

When the JPEG standard was defined, they also included the so-called "APP markers" --- types FFE0 through FFEF --- that were supposed to be used for "application-specific data." These are abused in various ways by various programs, but for the most part, they're meaningless, and can be safely ignored, with the exception of APP0 (FFE0), which is used for JFIF data: JFIF extends the JPEG standard slightly to include additional useful information like the DPI of the image.

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

The problem with your image is that it contains an FFE1 marker, with a size-zero chunk following that marker. It's otherwise unremarkable image data (a remarkable image, but unremarkable data) save for that weird little useless APP1 chunk. GDI+ is wrongly attempting to interpret that APP1 chunk, probably attempting to decode it as EXIF data, and it's blowing up. (My guess is that GDI+ is dying because it's attempting to actually process a size-zero array.) GDI+, if it was written correctly, would ignore any APPn chunks that it doesn't understand, but instead, it tries to make sense of data that is by definition nonstandard, and it bursts into flames.

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

So the solution is to write a little routine that will read your file into memory, strip out the unneeded APPn chunks (markers FFE1 through FFEF), and then feed the resulting "clean" image data into GDI+, which it will then process correctly.

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

We currently have a contest underway here at work to see who can write the JPEG-cleaning routine the fastest, with fun prizes :-)

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


For the naysayers: That image is not "slightly nonstandard." The image uses APP1 for its own purposes, and GDI+ is very wrong to try to process that data. Other applications have no trouble reading the image because they rightly ignore the APP chunks like they're supposed to.

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

#3


This thread from MSDN Forums may be useful.

来自MSDN论坛的这个帖子可能很有用。

The error may mean the data is corrupt or there is some underlying stream that has been close too early.

该错误可能意味着数据已损坏或存在一些过早关闭的基础流。

#4


The error can be a permission problem. Especially if your application is an ASP.NET application. Try moving the file to the same directory as your executable (if Win forms) or the root directory of your web application (if asp.net).

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

#5


I have the same problem.

我也有同样的问题。

The only difference i've noticed is the compression. It works fine with "JPEG" but when the compression is "Progressive JPEG" i get the exception (A generic error occurred in GDI+).

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

At first i thought it could be a memory problem because the images i mentioned were kind of big (about 5MB in disk and maybe ~80MB in memory), but then i'v noticed the difference in the compression type.

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

When i open/save the image file in other program like IrfanView or GIMP, the result is ok, but that's not the idea.

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

#1


.Net isn't handling the format of that particular image, potentially because the jpeg data format is slightly broken or non-standard. If you load the image into GIMP and save to a new file you can then load it with the Image class. Presumably GIMP is a bit more forgiving of file format problems.

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

#2


There's an exact answer to this problem. We ran into this at work today, and I was able to prove conclusively what's going on here.

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

The JPEG standard defines a metadata format, a file that consists of a series of "chunks" of data (which they call "segments"). Each chunk starts with FF marker, followed by another marker byte to identify what kind of chunk it is, followed by a pair of bytes that describe the length of the chunk (a 16-bit little-endian value). Some chunks (like FFD8, "Start of Image") are critical to the file's usage, and some (like FFFE, "Comment") are utterly meaningless.

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

When the JPEG standard was defined, they also included the so-called "APP markers" --- types FFE0 through FFEF --- that were supposed to be used for "application-specific data." These are abused in various ways by various programs, but for the most part, they're meaningless, and can be safely ignored, with the exception of APP0 (FFE0), which is used for JFIF data: JFIF extends the JPEG standard slightly to include additional useful information like the DPI of the image.

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

The problem with your image is that it contains an FFE1 marker, with a size-zero chunk following that marker. It's otherwise unremarkable image data (a remarkable image, but unremarkable data) save for that weird little useless APP1 chunk. GDI+ is wrongly attempting to interpret that APP1 chunk, probably attempting to decode it as EXIF data, and it's blowing up. (My guess is that GDI+ is dying because it's attempting to actually process a size-zero array.) GDI+, if it was written correctly, would ignore any APPn chunks that it doesn't understand, but instead, it tries to make sense of data that is by definition nonstandard, and it bursts into flames.

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

So the solution is to write a little routine that will read your file into memory, strip out the unneeded APPn chunks (markers FFE1 through FFEF), and then feed the resulting "clean" image data into GDI+, which it will then process correctly.

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

We currently have a contest underway here at work to see who can write the JPEG-cleaning routine the fastest, with fun prizes :-)

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


For the naysayers: That image is not "slightly nonstandard." The image uses APP1 for its own purposes, and GDI+ is very wrong to try to process that data. Other applications have no trouble reading the image because they rightly ignore the APP chunks like they're supposed to.

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

#3


This thread from MSDN Forums may be useful.

来自MSDN论坛的这个帖子可能很有用。

The error may mean the data is corrupt or there is some underlying stream that has been close too early.

该错误可能意味着数据已损坏或存在一些过早关闭的基础流。

#4


The error can be a permission problem. Especially if your application is an ASP.NET application. Try moving the file to the same directory as your executable (if Win forms) or the root directory of your web application (if asp.net).

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

#5


I have the same problem.

我也有同样的问题。

The only difference i've noticed is the compression. It works fine with "JPEG" but when the compression is "Progressive JPEG" i get the exception (A generic error occurred in GDI+).

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

At first i thought it could be a memory problem because the images i mentioned were kind of big (about 5MB in disk and maybe ~80MB in memory), but then i'v noticed the difference in the compression type.

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

When i open/save the image file in other program like IrfanView or GIMP, the result is ok, but that's not the idea.

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