为什么WriteableBitmap无法直接写入图像字节?

时间:2019-06-14 11:05:10

标签: c# wpf

我从套接字接收到由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);

1 个答案:

答案 0 :(得分:1)

如果是行

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}");
    }
}