【问题标题】:Error while loading JPEG: "A generic error occurred in GDI+."加载 JPEG 时出错:“GDI+ 中出现一般错误。”
【发布时间】:2010-11-11 17:56:46
【问题描述】:

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

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

我得到的异常是:“GDI+ 中发生一般错误。”,这真的不是很有帮助。有没有其他人遇到过这个问题,或者知道解决方法?

注意:如果你想测试这个问题,你可以download a test image 这在 C# 中不起作用。

【问题讨论】:

  • 我喜欢这个错误,它还不如说,“嘿,哟,发生了一些垃圾。去检查。”你会认为微软至少会为没有告诉你任何有意义的事情而道歉,比如“很抱歉,但除了 GDI+ 遇到了一个一般性错误之外,不能告诉你更多。”

标签: c# image gdi+


【解决方案1】:

这个thread from MSDN Forums 可能有用。

该错误可能意味着数据已损坏 或者有一些底层流 太早了。

【讨论】:

  • .NET 肯定认为图像已损坏,但我知道这很好,因为它会在图像编辑器“GIMP”中加载。
  • 假设这不是权限问题,它是否在 Paint.NET 中正确打开(因为它也使用 .NET)?
  • 那么-locster 可能是正确的;这意味着图像有点无聊,以至于 .NET Jpeg 处理库无法接受它,而像 GIMP 这样的图像处理应用程序没有这个问题。
  • 我刚刚测试了您提供的测试图像。它在 Windows 7 RC 上的 Paint.NET v3.36 上为我打开。由于 Windows 7 具有最新的 .NET 3.5 位,因此可能是您使用的框架特有的问题?您是否尝试过为您的框架应用最新的服务包?
  • @sigint:我使用的是带有所有最新 .NET 3.5 更新的 Windows XP。我将在 Windows 7 上尝试。也许 Windows 7 中的幕后 GDI+ 有更新。
【解决方案2】:

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

【讨论】:

  • 我可以从同一位置加载其他图像文件。图像文件在哪里无关紧要,它不会加载。
【解决方案3】:

.Net 没有处理该特定图像的格式,可能是因为 jpeg 数据格式略有损坏或不标准。如果您将图像加载到 GIMP 并保存到一个新文件,您可以使用 Image 类加载它。据推测,GIMP 对文件格式问题的容忍度更高。

【讨论】:

  • 是的,重新保存图片确实可以解决问题。我想知道的是为什么C#不能加载这个图像,而非.NET应用程序没有问题。
  • 文件的内部结构很可能违反了 jpeg 标准 - GIMP 和其他程序能够处理这个问题。这种情况并不少见,即某些标准的早期实现包含错误或规范含糊不清,并且该错误成为事实上的标准。该类或 Image 类确实包含错误或不完全支持 JPEG 标准。
【解决方案4】:

这个问题有一个确切的答案。我们今天在工作中遇到了这个问题,我能够确凿地证明这里发生了什么。

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 块。

【讨论】:

    【解决方案5】:

    我也有同样的问题。

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

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

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

    【讨论】:

    • 我昨天尝试了相同的代码,它运行良好。我猜在 .NET Framework 的众多更新之一中,添加了对 Progressive JPEG 的支持。
    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多