Create a BitmapImage from a byte array
Asked Answered
T

2

6

I am creating a byte array with arbitrary values in it and want to convert it into a BitmapImage.

    bi = new BitmapImage();
    using (MemoryStream stream = new MemoryStream(data))
    {
      try
      {
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.StreamSource = stream;
        bi.DecodePixelWidth = width;

        bi.EndInit();

      }
      catch (Exception ex)
      {
        return null;
      }
    }

This code gives me a NotSupportedException all the time. How could I create a BitmapSource from any byte array?

Tades answered 7/3, 2013 at 15:12 Comment(1)
Perhaps you want to do this: How can I convert byte[] to BitmapImage (asked today). If so, the question is likely to be closed as duplicate.Hagans
H
9

Given an array of bytes where each byte represents a pixel value, you may create a grayscale bitmap like shown below. You need to specify the width and height of the bitmap, and that must of course match the buffer size.

byte[] buffer = ... // must be at least 10000 bytes long in this example

var width = 100; // for example
var height = 100; // for example
var dpiX = 96d;
var dpiY = 96d;
var pixelFormat = PixelFormats.Gray8; // grayscale bitmap
var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8; // == 1 in this example
var stride = bytesPerPixel * width; // == width in this example

var bitmap = BitmapSource.Create(width, height, dpiX, dpiY,
                                 pixelFormat, null, buffer, stride);

Each byte value may also represent an index into a color palette, in which case your would have to specify PixelFormats.Indexed8 and of course also pass in an appropriate color palette.

Hagans answered 8/3, 2013 at 9:1 Comment(3)
I think you mean doing a division, not multiplication by 8 var bytesPerPixel = (pixelFormat.BitsPerPixel + 7) / 8; // == 1 in this exampleWenn
I have elaborated in a question here with your code. If you can show were my malfunction is I will gladly remove all these comments.Partnership
I find it easier to just pass zero for dpiX and dpiY. The resulting bitmap will have exactly width x height Pixels. Passing 96 seems to work just fine, but I'm not sure if this is guaranteed behavior or if it could change, e.g. depending on some system settings.Aeschines
A
1

The byte array must contain valid image data (PNG / JPG / BMP). If you remove the using-block and the data is valid then your Code should work. BitmapImage doesn't seem to load the image immediatly, so it can't load it afterwards because the stream is already disposed.

What do you mean by "arbitrary values"? Random RGB values? Then I propose to use the Bitmap class and save the resulting Bitmap in a Memorystream.

If you just want to bind a Byte[] to and Image Control in your userinterface: Bind directly to the array. It works without a converter.

Adventurous answered 7/3, 2013 at 16:5 Comment(2)
The bi.CacheOption = BitmapCacheOption.OnLoad will force the stream to be read and will allow the stream to be disposed.Solicitude
In my example I mean a byte array that is filled with values between 0 and 255.Tades

© 2022 - 2024 — McMap. All rights reserved.