0

我有一个从相机拍摄的有效 jpeg 帧:

http://www.developerinabox.com/test.jpg

我正在使用以下(示例)代码加载它:

using System.Net;
using System.Drawing;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            WebRequest req = WebRequest.Create("http://www.developerinabox.com/test.jpg");
            req.Timeout = 5000;
            WebResponse resp = null;


            resp = req.GetResponse();
            if (resp != null)
            {
                var s = resp.GetResponseStream();
                if (s != null)
                {
                    Image img = Image.FromStream(s); //<-- Error thrown here
                }
            }


        }
    }
}

在 Windows XP/Vista/7 中这工作正常。

在 Windows 8 中,它因“gdi+ 中的一般错误”而失败,我尝试通过 WPF 加载它,结果相同。

我可以在我的 Windows 8 PC 上用谷歌浏览器显示图像,但不能在 IE 中显示。它将同时显示在 Windows XP/Vista/7 上。

我可以在 Fireworks 中的 Windows 8 盒子上打开它,但尝试在油漆中打开它会给我:

“这不是一个有效的位图文件,或者它的格式目前不受支持。”

有任何想法吗?

4

1 回答 1

3

实际上,它是无效的 JPEG 图像,但正如您所见,许多应用程序可以无缝解码此图像。此 JPEG 图像有一个虚假的 SOS 标记(抱歉提供技术信息),此扫描标头(SOS) 表示此图像具有 1 个颜色分量,但帧标头(SOF,出现在 JPEG 文件结构中的 SOS 之前) 声称这是一个3 个组件的图像。

因此,Scan 标头的信息少于所需的信息,但可以将缺失的信息替换为默认值,并且 JPEG 图像应该被毫无问题地解码,这正是正在发生的事情。缺少的信息是霍夫曼表索引,这些索引的默认集可以基于 JPEG 编码类型(顺序、渐进或无损)来假设。

嗯,在JPEG解码方面,Win8似乎更严格。如果您好奇,您可以查看我为另一个 JPEG 相关问题上传的代码(它在 VB.NET 中编码),您可以对其进行调试以了解问题所在(您也应该检查 JPEG 规范)。


编辑: 毕竟这是一个有效的 JPEG 图像

此 JPEG 是基线多扫描顺序图像(类似于平面图像),不要与逐行图像(类似于隔行图像)混淆。因此,此 JPEG 具有较小的Scan 标头,因为图像一次解码一个组件。因此,该文件有 3 个不连续的扫描头( SOS for 1st component, compressed data, SOS for 2nd component, compressed data,...),每个扫描头都有单个组件的信息。
最后,如果问题是不完整或伪造的扫描标头,则有一种解决方法(您可以修复伪造的 SOS 标头),但事实并非如此。因此,您可以向 MS 人员提出请求,寻求支持Win8 上的多扫描顺序JPEG 图像 ;-) 或使用一些第三方 JPEG 解码库。

于 2012-11-01T03:28:37.510 回答