C# 在 WPF 中显示 Drawing.Image

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10077498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 12:22:32  来源:igfitidea点击:

Show Drawing.Image in WPF

c#wpfimage

提问by user896692

I′ve got an instance of System.Drawing.Image.

我有一个 System.Drawing.Image 的实例。

How can I show this in my WPF-application?

如何在我的 WPF 应用程序中显示它?

I tried with img.Sourcebut that does not work.

我试过了,img.Source但这不起作用。

回答by AlexDrenea

To load an Image into a WPF Image control you will need a System.Windows.Media.ImageSource.

要将图像加载到 WPF 图像控件中,您需要一个 System.Windows.Media.ImageSource。

You need to convert your Drawing.Image object to an ImageSource object :

您需要将您的 Drawing.Image 对象转换为 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;
    }

Declaration of the DeleteObject method.

DeleteObject 方法的声明。

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

回答by Badiboy

I have the same problem and solve it by combining several answers.

我有同样的问题,并通过结合几个答案来解决它。

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

From this question and answers

这个问题和答案

回答by burnttoast11

If you use a converter, you can actually bind to the Imageobject. You will just need to create an IValueConverterthat will convert the Imageto a BitmapSource.

如果使用转换器,则实际上可以绑定到Image对象。您只需要创建一个IValueConverter将 转换Image为 的BitmapSource

I used AlexDrenea's sample code inside the converter to do the real work.

我在转换器中使用了 AlexDrenea 的示例代码来完成实际工作。

[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)
    {
        if (value is null || !(value is Image myImage))
        {//ensure provided value is valid image.
            return null;
        }

        if (myImage.Height > Int16.MaxValue || myImage.Width > Int16.MaxValue)
        {//GetHbitmap will fail if either dimension is larger than max short value.
            //Throwing here to reduce cpu and resource usage when error can be detected early.
            throw new ArgumentException($"Cannot convert System.Drawing.Image with either dimension greater than {Int16.MaxValue} to BitmapImage.\nProvided image's dimensions: {myImage.Width}x{myImage.Height}", nameof(value));
        }

        using Bitmap bitmap = new Bitmap(myImage); //ensure Bitmap is disposed of after usefulness is fulfilled.
        IntPtr bmpPt = bitmap.GetHbitmap();
        try
        {
            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();
            return bitmapSource;
        }
        finally
        { //done in a finally block to ensure this memory is not leaked regardless of exceptions.
            DeleteObject(bmpPt);
        }
    }

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

In your XAML you will need to add the converter.

在您的 XAML 中,您需要添加转换器。

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

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