加载 JPEG 时出错:“GDI 中发生一般错误”。
我有一些 JPEG 文件,但似乎无法加载到我的 C# 应用程序中。 它们可以很好地加载到其他应用程序中,例如 GIMP。 这是我用来加载图像的代码行:
System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:\Image.jpg");
我得到的异常是:“GDI+ 中发生一般错误。”,这确实不是很有帮助。 还有其他人遇到过这个问题,或者知道解决方法吗?
注意:如果您想测试该问题,可以下载测试图像在 C# 中不起作用。
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:
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?
Note: If you would like to test the problem you can download a test image that doesn't work in C#.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我也有同样的问题。
我注意到的唯一区别是压缩。 它适用于“JPEG”,但当压缩为“渐进式 JPEG”时,我得到异常(GDI+ 中发生一般错误)。
起初我认为这可能是内存问题,因为我提到的图像有点大(磁盘大约 5MB,内存大约 80MB),但后来我注意到压缩类型的差异。
当我在 IrfanView 或 GIMP 等其他程序中打开/保存图像文件时,结果是好的,但这不是想法。
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+).
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.
When i open/save the image file in other program like IrfanView or GIMP, the result is ok, but that's not the idea.
这个问题有一个确切的答案。 我们今天在工作中遇到了这个问题,我能够最终证明这里发生了什么。
JPEG 标准定义了一种元数据格式,即由一系列数据“块”(他们称之为“段”)组成的文件。 每个块以 FF 标记开始,后面跟着另一个标记字节来标识它是什么类型的块,然后是一对描述块长度的字节(一个 16 位小端值)。 有些块(如 FFD8,“图像开始”)对于文件的使用至关重要,而有些块(如 FFFE,“注释”)则完全没有意义。
定义 JPEG 标准时,它们还包括所谓的“APP 标记”(FFE0 到 FFEF 类型),这些标记应该用于“特定于应用程序的数据”。 这些被各种程序以各种方式滥用,但在大多数情况下,它们毫无意义,可以安全地忽略,但 APP0 (FFE0) 除外,它用于 JFIF 数据:JFIF 将 JPEG 标准稍微扩展为包括其他有用的信息,例如图像的 DPI。
您的图像的问题是它包含FFE1标记,该标记后面有一个大小为零的块。 除了那个奇怪的无用的 APP1 块之外,它是其他不起眼的图像数据(一个引人注目的图像,但不起眼的数据)。 GDI+ 错误地尝试解释该 APP1 块,可能试图将其解码为 EXIF 数据,然后它就崩溃了。 (我的猜测是 GDI+ 正在消亡,因为它正在尝试实际处理大小为零的数组。)如果编写正确,GDI+ 将忽略任何它不理解的 APPn 块,但相反,它会尝试理解数据从定义上来说是非标准的,并且会突然起火。
因此,解决方案是编写一个小例程,将文件读入内存,去掉不需要的 APPn 块(标记 FFE1 到 FFEF),然后将生成的“干净”图像数据输入 GDI+,然后它将正确处理。
我们目前正在进行一场竞赛,看看谁能最快地编写 JPEG 清理例程,并获得有趣的奖品:-)
对于反对者:该图像“不是”“有点不标准”。 ” 该图像使用 APP1 来达到其自身目的,而 GDI+ 尝试处理该数据是非常错误的。 其他应用程序在读取图像时没有任何问题,因为它们正确地忽略了应用程序块,就像它们应该做的那样。
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.
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.
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.
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.
We currently have a contest underway here at work to see who can write the JPEG-cleaning routine the fastest, with fun prizes :-)
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.
.Net 不处理该特定图像的格式,可能是因为 jpeg 数据格式稍微损坏或不标准。 如果将图像加载到 GIMP 中并保存到新文件中,则可以使用 Image 类加载它。 想必 GIMP 对文件格式问题更宽容一些。
.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.
此来自 MSDN 论坛的帖子< /a> 可能有用。
This thread from MSDN Forums may be useful.
该错误可能是权限问题。 特别是如果您的应用程序是 ASP.NET 应用程序。 尝试将文件移动到与可执行文件(如果是 Win 形式)或 Web 应用程序的根目录(如果是 asp.net)相同的目录。
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).