【问题标题】:Cannot decode jpeg using JpegBitmapDecoder无法使用 JpegBitmapDecoder 解码 jpeg
【发布时间】:2012-04-23 09:27:35
【问题描述】:

我有以下两个函数将字节转换为图像并在 WPF 中的图像上显示

 private JpegBitmapDecoder ConvertBytestoImageStream(byte[] imageData)
        {
            Stream imageStreamSource = new MemoryStream(imageData);            

            JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapSource = decoder.Frames[0];

            return decoder;
        }

上面的代码根本不起作用。我总是收到“未找到成像组件”图像未显示的异常。

private MemoryStream ConvertBytestoImageStream(int CameraId, byte[] ImageData, int imgWidth, int imgHeight, DateTime detectTime)
    {  
        GCHandle gch = GCHandle.Alloc(ImageData, GCHandleType.Pinned);
        int stride = 4 * ((24 * imgWidth + 31) / 32);
        Bitmap bmp = new Bitmap(imgWidth, imgHeight, stride, PixelFormat.Format24bppRgb, gch.AddrOfPinnedObject());
        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, ImageFormat.Jpeg);
        gch.Free();

        return ms;
    }

此功能有效,但速度很慢。我希望优化我的代码。

【问题讨论】:

  • 我不太清楚 imageData 传递给 ConvertBytestoImageStream 的内容。它是 JPEG 缓冲区还是原始像素数据?

标签: wpf jpeg decoder


【解决方案1】:

如果我将 JPEG 缓冲区传递给您的 ConvertBytestoImageStream,它对我来说可以正常工作。然而,有一些事情可以改进。根据您是否真的要返回解码器或位图,该方法可以这样编写:

private BitmapDecoder ConvertBytesToDecoder(byte[] buffer)
{
    using (MemoryStream stream = new MemoryStream(buffer))
    {
        return BitmapDecoder.Create(stream,
            BitmapCreateOptions.PreservePixelFormat,
            BitmapCacheOption.OnLoad); // enables closing the stream immediately
    }
}

或者这样:

private ImageSource ConvertBytesToImage(byte[] buffer)
{
    using (MemoryStream stream = new MemoryStream(buffer))
    {
        BitmapDecoder decoder = BitmapDecoder.Create(stream,
            BitmapCreateOptions.PreservePixelFormat,
            BitmapCacheOption.OnLoad); // enables closing the stream immediately
        return decoder.Frames[0];
    }
}

请注意,此代码不使用 JpegBitmapDecoder,而是使用抽象基类 BitmapDecoder 的静态工厂方法,该方法会自动为提供的数据流选择合适的解码器。因此,此代码可用于 WPF 支持的所有图像格式。

还要注意,Stream 对象在 using block 中使用,它会在不再需要时处理它。 BitmapCacheOption.OnLoad 确保将整个流加载到解码器中,然后可以关闭。

【讨论】:

  • 好吧,我的错,传递的缓冲区是位图缓冲区本身。那么如何增强此代码 GCHandle gch = GCHandle.Alloc(ImageData, GCHandleType.Pinned); int 步幅 = 4 * ((24 * imgWidth + 31) / 32);位图 bmp = new Bitmap(imgWidth, imgHeight, stride, PixelFormat.Format24bppRgb, gch.AddrOfPinnedObject());内存流毫秒 = 新的内存流(); bmp.Save(ms, ImageFormat.Jpeg); gch.Free();
猜你喜欢
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 2010-12-06
相关资源
最近更新 更多