xunhaohw
xunhaohw

Reputation: 1

Why WriteableBitmap can not be write the image bytes directly?

I recieve the image bytes from socket which send by minicap continuous. When I save the bytes to a image, the image can be open normally. but when I render the bytes to WriteableBitmap, it is not work, the code as below:

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

    }

When I modify it below, it is normal to work, the question is I do not want to do any convert, because speed matters.

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

the writeableBitmap is defined:

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

Upvotes: 0

Views: 259

Answers (1)

Clemens
Clemens

Reputation: 128013

If the line

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

successfully creates a BitmapSource, the frameBody argument does not contain a raw pixel buffer. Instead, it is an encoded image frame like e.g. a PNG, JPEG, BMP or similar.

It is unclear why you think you need a WriteableBitmap at all. Just assign bms to the Image element's Source property:

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

If really necessary, you may also easily control the size of the decoded bitmap by creating a BitmapImage and setting either its DecodePixelWidth or DecodePixelHeight property:

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

Upvotes: 1

Related Questions