byte array to WriteableBitmap image IValueConverte

2020-03-08 07:50发布

问题:

I have been tackling this problem for some time. I get the image from my DB as a byte[] and i want to convert it to WritableBitmap so i can use binding to show it on my xaml page.

I am using this:

 public class ImageConverter : IValueConverter
{
    /// <summary>
    /// Converts a Jpeg byte array into a WriteableBitmap
    /// </summary>
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is byte[])
        {
            MemoryStream stream = new MemoryStream((Byte[])value);
            WriteableBitmap bmp = new WriteableBitmap(200, 200);
            bmp.LoadJpeg(stream);
            return bmp;
        }
        else
            return null;
    }
    /// <summary>
    /// Converts a WriteableBitmap into a Jpeg byte array.
    /// </summary>
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The first problem is that it doesn't work. it throws an unspecified exception when it hits bmp.LoadJpeg(stream);

The second problem is regarding the fixed size passed to the WriteableBitmap constructor, how can i know the size of the photo that is coming from the db ? can i make it dynamic somehow ? I guess the second problem is the cause of the first one.

Thanks.

EDIT

I have also tries using PictureDecoder.DecodeJpeg() like this:

            MemoryStream stream = new MemoryStream((Byte[])value);
            WriteableBitmap bmp = PictureDecoder.DecodeJpeg(stream);
            return bmp;

but it didn't work either. in this case PictureDecoder.DecodeJpeg suppose to create the bmp object for me. I still get an unspecified error. could it be that i passed the maximum length allowed for the stream ?

回答1:

I use this but it returns BitmapImage. Do you need WriteableBitmap returned?

edit: as Ritch mentioned in the comments if you do need to return WriteableBitmap add

var writeableBitmap = new WriteableBitmap(bitmapImage);
return writeableBitmap

The second problem is regarding the fixed size passed to the WriteableBitmap constructor, how can i know the size of the photo that is coming from the db ?

Once the BitmapImage is created you have access to bitmapImage.PixelWidth and bitmapImage.PixelHeight.

 public class ByteArraytoImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return null;

            var byteBlob = value as byte[];
            var ms = new MemoryStream(byteBlob);
            var bmi = new BitmapImage();
            bmi.SetSource(ms);
            return bmi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


回答2:

Thanks for your answer

It seems that the problem was that the stream coming from the db was corrupted somehow. the value converter was actually okay. i have changed it to use PictureDecoder.DecodeJpeg() instead so it will be more clean and dynamic

public class ImageConverter : IValueConverter
{
/// <summary>
/// Converts a Jpeg byte array into a WriteableBitmap
/// </summary>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (value is byte[])
    {
        MemoryStream stream = new MemoryStream((Byte[])value);
        WriteableBitmap bmp = PictureDecoder.DecodeJpeg(stream);
        return bmp;
    }
    else
        return null;
}
/// <summary>
/// Converts a WriteableBitmap into a Jpeg byte array.
/// </summary>
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    throw new NotImplementedException();
}
}