0

I am trying to download images from a website, convert them to base-64 strings so they can be serialized to a file, deserialize, convert from base-64 string to System.Drawing.Image and then finally convert to System.Windows.Media.ImageSource so they can be data bound to my UI.

    public static string ImageToString(Image image)
    {
        using (var ms = new MemoryStream())
        {
            if (image == null)
                image = Properties.Resources.blank_image;

            image.Save(ms, image.RawFormat);
            return Convert.ToBase64String(ms.ToArray());
        }
    }

    public static Image StringToImage(string imageString)
    {
        if (String.IsNullOrEmpty(imageString))
            return Properties.Resources.blank_image;

        var array = Convert.FromBase64String(imageString);
        using (var ms = new MemoryStream(array))
        {
            return Image.FromStream(ms);
        }
    }

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

        var image = (System.Drawing.Image)value;
        var bitmap = new System.Windows.Media.Imaging.BitmapImage();

        bitmap.BeginInit();

        MemoryStream memoryStream = new MemoryStream();
        image.Save(memoryStream, image.RawFormat);
        memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
        bitmap.StreamSource = memoryStream;

        bitmap.EndInit();

        return bitmap;
    }

I get this rather unhelpful exception when image.Save(memoryStream, image.RawFormat) in Convert() is hit:

An exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll but was not handled in user code

Additional information: A generic error occurred in GDI+.

Converting my Properties.Resources.blank_image Image to ImageSource works fine, but not the base-64 string converted to Image.

Brett
  • 436
  • 3
  • 18
  • http://stackoverflow.com/questions/5813633/a-generic-error-occurs-at-gdi-at-bitmap-save-after-using-savefiledialog – Nathan Dec 14 '12 at 02:15
  • Also, I'm confused as to why you're serializing to a string in the first place? It seems a lot simpler to just save the image directly as a binary file. – Nathan Dec 14 '12 at 02:18
  • I'm using Protobuf-net and it doesn't support serializing images. – Brett Dec 14 '12 at 02:42

1 Answers1

1

I'm not sure about your particular exception (unless its related to A Generic error occurs at GDI+ at Bitmap.Save() after using SaveFileDialog), but there is another option.

You may have better luck converting directly from the base 64 string and using BitmapDecoder.Create(...)

For example something like:

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

    string imageBase64String = (string)value;
    byte[] imageAsBytes = Convert.FromBase64String(imageBase64String);

    using (var ms = new MemoryStream(imageAsBytes))
    {
        var decoder = System.Windows.Media.Imaging.BitmapDecoder.Create(ms, BitmapCreateOptions.None, BitmapCacheOptions.OnLoad);

        return decoder.Frames[0];
    }
} 
Community
  • 1
  • 1
Nathan
  • 10,593
  • 10
  • 63
  • 87