What is the easiest way to display an image from Byte[]?

2

I have a structure containing an image in black and white:

public class Img
{
    public int height;
    public int width;
    public byte[] matrix;
}

The values containing in matrix are 0 or 255.

What is the best way to display this image in a component using C# WPF?

I've try this :

XAML:

<Image Grid.Row="0"
       Stretch="Uniform"
       Source="{Binding Picture, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>

C#:

public BitmapImage Picture
{
    get
    {
        return _picture;
    }
    private set
    {
        _picture = value;
        OnPropertyChanged("Picture");
    }
}

public void Generate()
{
    Img img = CreateImg();
    Picture = LoadImage(img.width, img.height, img.matrix);
}

private BitmapImage LoadImage(int w, int h, byte[] imageData)
{
    using (MemoryStream memory = new MemoryStream(imageData))
    {
        memory.Position = 0;
        BitmapImage bitmapimage = new BitmapImage();
        bitmapimage.BeginInit();
        bitmapimage.StreamSource = memory;
        bitmapimage.EndInit();
        return bitmapimage;
    }
}

But it doesn't work:

"Exception from HRESULT : 0x88982F50"

c#
wpf
image
asked on Stack Overflow Jul 20, 2016 by A.Pissicat • edited Jul 20, 2016 by Chris Dunaway

2 Answers

6

The BitmapImage.StreamSource property only accepts a stream that contains an encoded bitmap buffer, e.g. a PNG or JPEG.

In order to create a BitmapSource (the base class of BitmapImage) from raw pixel data, you may use the BitmapSource.Create() method. Depending on the number of bits per pixel, and the ordering of the alpha and color channels, you would also have to choose an appropriate PixelFormat.

Assuming an 8-bit grayscale format, you would create a BitmapSource like this:

private BitmapSource LoadImage(int width, int height, byte[] imageData)
{
    var format = PixelFormats.Gray8;
    var stride = (width * format.BitsPerPixel + 7) / 8;

    return BitmapSource.Create(width, height, 96, 96, format, null, imageData, stride);
}

Of course you would also have to change the type of your property to BitmapSource (which is more flexible anyway, since you can still assign a BitmapImage).

public BitmapSource Picture { get; set; }
answered on Stack Overflow Jul 20, 2016 by Clemens • edited Jul 20, 2016 by Clemens
0

Try this:

    private static BitmapImage LoadImage(byte[] imageData)
    {
        if (imageData == null || imageData.Length == 0) return null;
        var image = new BitmapImage();
        using (var mem = new MemoryStream(imageData))
        {
            mem.Position = 0;
            image.BeginInit();
            image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
            image.CacheOption = BitmapCacheOption.OnLoad;
            image.UriSource = null;
            image.StreamSource = mem;
            image.EndInit();
        }
        image.Freeze();
        return image;
    }
answered on Stack Overflow Jul 20, 2016 by (unknown user) • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0