C# 为什么WriteableBitmap不能直接写入图像字节?

C# 为什么WriteableBitmap不能直接写入图像字节?,c#,wpf,C#,Wpf,我从套接字接收图像字节,这些字节通过minicap continuous发送。当我将字节保存到图像时,图像可以正常打开。但当我将字节呈现给WriteableBitmap时,它不起作用,代码如下所示: void DrawUI(ref byte[] frameBody) { try { writeableBitmap.WritePixels(new Int32Rect(0, 0, 1080, 1920), frameBody,

我从套接字接收图像字节,这些字节通过minicap continuous发送。当我将字节保存到图像时,图像可以正常打开。但当我将字节呈现给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);
如果这条线

BitmapSource bms = (BitmapSource)new ImageSourceConverter().ConvertFrom(frameBody);
成功创建位图源时,
frameBody
参数不包含原始像素缓冲区。相反,它是一个编码图像帧,如PNG、JPEG、BMP或类似文件

现在还不清楚为什么你认为你需要一个可写的位图。只需将
bms
分配给图像元素的
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}");
    }
}
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}");
    }
}
如果确实需要,您还可以通过创建位图图像并设置其
DecodePixelWidth
DecodePixelHeight
属性来轻松控制解码位图的大小:

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

ImageSourceConverter.ConvertFrom()
对编码图像帧(如PNG、JPEG或BMP)进行解码。这不是原始像素缓冲区。除此之外,当您已有
位图源bms
时,WriteableBitmap的用途是什么?我已将对象定义为:System.Windows.Controls.Image Image=Image();image.Source=writeableBitmap;这是正确的方法吗?为什么不指定
image.Source=bms?为什么是WriteableBitmap?同样
ref byte[]frameBody
似乎没有意义。声明不带ref参数的方法:
private void DrawUI(byte[]frameBody)
我发现writeableBitmap可以设置dpi参数来更改大小,因为原始图像太大了。欢迎使用。有关如何控制解码位图大小的信息,请参阅上一个代码示例。