首页 > 解决方案 > 为什么 WriteableBitmap 不能直接写入图像字节?

问题描述

我从通过 minicap 连续发送的套接字接收图像字节。当我将字节保存到图像时,图像可以正常打开。但是当我将字节渲染到 WriteableBitmap 时,它不起作用,代码如下:

    void DrawUI(ref byte[] frameBody)
    {
        try
        {
            writeableBitmap.WritePixels(new Int32Rect(0, 0, 1080, 1920), frameBody, writeableBitmap.BackBufferStride, 0);
        }
        catch(Exception e)
        {
            Console.WriteLine($"catch a exception {e.Message}");
        }

    }

当我在下面修改它时,它可以正常工作,问题是我不想做任何转换,因为速度很重要。

    void DrawUI(ref byte[] frameBody)
    {
        try
        {
            BitmapSource bms = (BitmapSource)new ImageSourceConverter().ConvertFrom(frameBody);
            var bytesPerPixel = bms.Format.BitsPerPixel / 8;
            var stride1 = bms.PixelWidth * bytesPerPixel;
            byte[] pixels2 = new byte[1080 * 1920 * stride1];
            writeableBitmap.WritePixels(new Int32Rect(0, 0, 1080, 1920), pixels2, stride1, 0);
        }
        catch(Exception e)
        {
            Console.WriteLine($"catch a exception {e.Message}");
        }
    }

writeableBitmap 定义:

writeableBitmap = new WriteableBitmap(
                                  //(int)p.win.ActualWidth,//DPI相关
                                  //(int)p.win.ActualHeight,//DPI相关
                                  1080,
                                  1920,
            300,
            300,
            PixelFormats.Bgr32,
            null);

标签: c#wpf

解决方案


如果线

BitmapSource bms = (BitmapSource)new ImageSourceConverter().ConvertFrom(frameBody);

成功创建 BitmapSource,frameBody参数不包含原始像素缓冲区。相反,它是一个编码的图像帧,例如 PNG、JPEG、BMP 或类似的。

目前还不清楚为什么您认为您需要一个 WriteableBitmap。只需分配bms给 Image 元素的Source属性:

private void DrawUI(byte[] frameBody)
{
    try
    {
        var bms = (BitmapSource)new ImageSourceConverter().ConvertFrom(frameBody);

        image.Source = bms;
    }
    catch (Exception e)
    {
        Debug.WriteLine($"catch a exception {e.Message}");
    }
}

如果确实需要,您还可以通过创建 BitmapImage 并设置其DecodePixelWidthDecodePixelHeight属性来轻松控制解码位图的大小:

private void DrawUI(byte[] frameBody)
{
    try
    {
        var bitmap = new BitmapImage();

        using (var stream = new MemoryStream(frameBody))
        {
            bitmap.BeginInit();
            bitmap.DecodePixelWidth = 1080;
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.StreamSource = stream;
            bitmap.EndInit();
        }

        image.Source = bitmap;
    }
    catch (Exception e)
    {
        Debug.WriteLine($"catch a exception {e.Message}");
    }
}

推荐阅读