Oh My Dog
Oh My Dog

Reputation: 801

WPF Bitmap binding with GDI+ exception

I met a image display on WPF problem:

VIEWMODEL:

private Bitmap _bmp = null;
public Bitmap Bmp { get { return _bmp; }set { SetProperty(ref _bmp,value); } }

XAML:

<Image Source="{Binding Bmp, Converter={StaticResource M}}" Margin="10,34,10,10" />

CONVERTER:

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

    System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)value;
    System.IO.MemoryStream ms = new System.IO.MemoryStream();
    if (bmp.RawFormat.Guid == System.Drawing.Imaging.ImageFormat.MemoryBmp.Guid)
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
    else
        bmp.Save(ms, bmp.RawFormat);

    ms.Seek(0, System.IO.SeekOrigin.Begin);
    System.Windows.Media.Imaging.BitmapImage bi = new System.Windows.Media.Imaging.BitmapImage();
    bi.BeginInit();
    bi.StreamSource = ms;
    bi.EndInit();
    return bi;
}

I click a button to select a local image and read this image like this:

public Bitmap LoadBitmap(string filePath)
{
    using (var fs = new FileStream(filePath, FileMode.Open))
    {
        return new Bitmap(fs);
    }
}

then I set this image to bindable Bmp in ViewModel:

private void button_Click(object sender, RoutedEventArgs e)
{
    OpenFileDialog dialog = new OpenFileDialog();
    var b = dialog.ShowDialog();
    if (b == true)
    {
        Bitmap bmp = LoadBitmap(dialog.FileName);

        MViewModel m = this.DataContext as MViewModel;
        m.Bmp = bmp;
    }
}

some images works fine:

enter image description here

but some images not work(a GDI+ general error raised):

enter image description here

I don't know too much thing about Image format things, but when I debug these 2 bitmap objects, the only difference i can found is:

the one worked:

enter image description here

the one raised GDI+ error:

enter image description here

BUT, when I change the worked-image to Format8bppIndexed(in photoshop), then debug this image, displayed format32bppArgb.

enter image description here

so I thing the error because of format8bppIndex pixelFormat...right?

then, how can I fix this problem? thank you very much.

Upvotes: 0

Views: 174

Answers (1)

Clemens
Clemens

Reputation: 128070

Do not use System.Drawing.Bitmap in a WPF application without good reason. The WPF classes BitmapImage and BitmapFrame allow to create bitmap objects from file paths or streams, so you should change your code to this:

private BitmapSource _bmp = null;
public BitmapSource Bmp
{
    get { return _bmp; }
    set { SetProperty(ref _bmp, value); }
}

...

public BitmapSource LoadBitmap(string filePath)
{
    using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        var bitmap = new BitmapImage();
        bitmap.BeginInit();
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = fs;
        bitmap.EndInit();
        return bitmap;
    }
}

or, if also need to have access to bitmap metadata:

public BitmapSource LoadBitmap(string filePath)
{
    using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
    {
        return BitmapFrame.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    }
}

or, without a Stream directly from a path:

public BitmapSource LoadBitmap(string filePath)
{
    return new BitmapImage(new Uri(filePath));
}

or:

public BitmapSource LoadBitmap(string filePath)
{
    return BitmapFrame.Create(new Uri(filePath));
}

Then you would not need a binding converter:

<Image Source="{Binding Bmp}" Margin="10,34,10,10" />

Upvotes: 1

Related Questions