2016-05-03 1 views
0

traf ich eine Bildanzeige auf WPF Problem:WPF Bitmap Bindung mit GDI + Ausnahme

Ansichtsmodell:

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" /> 

WANDLER:

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 Klicken Sie auf eine Schaltfläche, um ein lokales Bild auszuwählen und zu bestätigen d dieses Bild wie folgt aus:

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

dann setze ich dieses Bild Bmp in Ansichtsmodell Bindable:

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; 
    } 
} 

einige Bilder funktioniert:

enter image description here

aber einige Bilder nicht funktionieren (ein GDI + allgemeiner Fehler wurde ausgelöst):

enter image description here

ich nicht zu viel, was über Bildformat Dinge wissen, aber wenn ich diese 2 Bitmap-Objekte debuggen, ich der einzige Unterschied ist, finden kann:

derjenige gearbeitet:

enter image description here

die einen erhöhten GDI + Fehler:

enter image description here

ABER, wenn ich die bearbeitetes ändern -Image auf Format8bppIndexed (in Photoshop), debuggen Sie dann dieses Bild, angezeigte format32bppArgb.

enter image description here

so dass ich, was der Fehler wegen format8bppIndex Pixelformat ... nicht wahr?

dann, wie kann ich dieses Problem beheben? vielen Dank.

+0

Was ist der Grund ein Ansichtsmodell-Eigenschaft vom Typ haben 'System.Drawing.Bitmap'? Wenn Sie nur Bitmaps aus Dateien laden, können Sie dies problemlos mit der WPF BitmapImage-Klasse (oder BitmapFrame oder BitmapDecoder) durchführen. Es scheint keine Notwendigkeit für WinForms/GDI Zeug hier zu geben. – Clemens

+0

@Clemens, kein Grund, das erste Mal wpf lernen Ich war Bitmap verwenden, das ist alles. Aber von deinem Posten aus ist es ein Glück, dass ich weiß, dass ich jetzt falsch liege. vielen Dank. –

Antwort

1

Verwenden Sie keine System.Drawing.Bitmap in einer WPF-Anwendung ohne triftigen Grund.Die WPF-Klassen BitmapImage und BitmapFrame erlauben Bitmap-Objekte von Dateipfaden oder Streams zu erzeugen, so sollten Sie Ihren Code dies ändern:

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; 
    } 
} 

oder, wenn auch Zugriff auf Bitmap-Metadaten haben müssen:

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

oder ohne Strom direkt von einem Pfad:

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

oder:

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

Dann würden Sie kein bindendes Konverter benötigen:

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