简体   繁体   中英

How to get BitmapImage from byte array in several different ImageFormats

I have saved images in our database by using the following method to convert them to byte arrays in different ImageFormats:

public byte[] foo()
{
    Image img = Image.FromFile(path);
    var tmpStream = new MemoryStream();
    ImageFormat format = img.RawFormat;
    img.Save(tmpStream, format);
    tmpStream.Seek(0, SeekOrigin.Begin);
    var imgBytes = new byte[MAX_IMG_SIZE];
    tmpStream.Read(imgBytes, 0, MAX_IMG_SIZE);
    return imgBytes;
}

Now I need to read them out and convert them back into the BitmapImage type so I can display them to the user. I was thinking about using the Image.FromStream(Stream) method but that doesn't seem to take into account the different ImageFormats... Anyone know what to do? Thanks in advance.

You shouldn't use classes from the WinForms System.Drawing namespace in a WPF application (like you do with Image.FromFile ).

WPF provides its own set of classes to load and save bitmaps from Streams and URIs, and has built-in support for automatically detecting the format of a bitmap frame buffer.

Just create a BitmapImage or a BitmapFrame directly from a Stream:

public static BitmapSource BitmaSourceFromByteArray(byte[] buffer)
{
    var bitmap = new BitmapImage();

    using (var stream = new MemoryStream(buffer))
    {
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.EndInit();
    }

    bitmap.Freeze(); // optionally make it cross-thread accessible
    return bitmap;
}

or

public static BitmapSource BitmaSourceFromByteArray(byte[] buffer)
{
    using (var stream = new MemoryStream(buffer))
    {
        return BitmapFrame.Create(
            stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    }
}

Either method returns a BitmapSource , which is the base class of BitmapImage and BitmapFrame, and should be sufficient to deal with bitmaps in the rest of your application. Eg the Source property of an Image control use another base class, ImageSource , as property type.

Note also that when you load a BitmapSource from a Stream that is to be closed after loading, you have to set BitmapCacheOption.OnLoad . Otherwise the Stream must be kept open until the bitmap is eventually shown.


For encoding a BitmapSource you should be using a method like this:

public static byte[] BitmapSourceToByteArray(BitmapSource bitmap)
{
    var encoder = new PngBitmapEncoder(); // or any other BitmapEncoder

    encoder.Frames.Add(BitmapFrame.Create(bitmap));

    using (var stream = new MemoryStream())
    {
        encoder.Save(stream);
        return stream.ToArray();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM