web-dev-qa-db-fra.com

Afficher Drawing.Image dans WPF

J'ai une instance de System.Drawing.Image.

Comment puis-je afficher cela dans mon application WPF?

J'ai essayé avec img.Source mais cela ne fonctionne pas.

24
user896692

J'ai le même problème et je le résous en combinant plusieurs réponses.

System.Drawing.Bitmap bmp;
Image image;
...
using (var ms = new MemoryStream())
{
    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
    ms.Position = 0;

    var bi = new BitmapImage();
    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.OnLoad;
    bi.StreamSource = ms;
    bi.EndInit();
}

image.Source = bi;
//bmp.Dispose(); //if bmp is not used further. Thanks @Peter

De cette question et réponses

24
Badiboy

Pour charger une image dans un contrôle d'image WPF, vous aurez besoin d'un System.Windows.Media.ImageSource.

Vous devez convertir votre objet Drawing.Image en un objet ImageSource:

 public static BitmapSource GetImageStream(Image myImage)
    {
        var bitmap = new Bitmap(myImage);
        IntPtr bmpPt = bitmap.GetHbitmap();
        BitmapSource bitmapSource =
         System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
               bmpPt,
               IntPtr.Zero,
               Int32Rect.Empty,
               BitmapSizeOptions.FromEmptyOptions());

        //freeze bitmapSource and clear memory to avoid memory leaks
        bitmapSource.Freeze();
        DeleteObject(bmpPt);

        return bitmapSource;
    }

Déclaration de la méthode DeleteObject.

[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool DeleteObject(IntPtr value);
20
AlexDrenea

Si vous utilisez un convertisseur, vous pouvez réellement vous lier à l'objet Image. Vous aurez juste besoin de créer un IValueConverter qui convertira le Image en BitmapSource.

J'ai utilisé l'exemple de code d'AlexDrenea à l'intérieur du convertisseur pour faire le vrai travail.

[ValueConversion(typeof(Image), typeof(BitmapSource))]
public class ImageToBitmapSourceConverter : IValueConverter
{
    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool DeleteObject(IntPtr value);

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Image myImage = (Image)value;

        var bitmap = new Bitmap(myImage);
        IntPtr bmpPt = bitmap.GetHbitmap();
        BitmapSource bitmapSource =
         System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
               bmpPt,
               IntPtr.Zero,
               Int32Rect.Empty,
               BitmapSizeOptions.FromEmptyOptions());

        //freeze bitmapSource and clear memory to avoid memory leaks
        bitmapSource.Freeze();
        DeleteObject(bmpPt);

        return bitmapSource;
    }

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

Dans votre XAML, vous devrez ajouter le convertisseur.

<utils:ImageToBitmapSourceConverter x:Key="ImageConverter"/>

<Image Source="{Binding ThumbSmall, Converter={StaticResource ImageConverter}}"
                   Stretch="None"/>
13
burnttoast11