Reputation: 801
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:
but some images not work(a GDI+ general error raised):
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:
the one raised GDI+ error:
BUT, when I change the worked-image to Format8bppIndexed(in photoshop), then debug this image, displayed format32bppArgb.
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
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