Show Drawing.Image in WPF

后端 未结 3 864
我寻月下人不归
我寻月下人不归 2020-11-29 08:24

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

How can I show this in my WPF-application?

I tried with img.Source but that does not work.

相关标签:
3条回答
  • 2020-11-29 08:52

    If you use a converter, you can actually bind to the Image object. You will just need to create an IValueConverter that will convert the Image to a BitmapSource.

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

    [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.

    <utils:ImageToBitmapSourceConverter x:Key="ImageConverter"/>
    
    <Image Source="{Binding ThumbSmall, Converter={StaticResource ImageConverter}}"
                       Stretch="None"/>
    
    0 讨论(0)
  • 2020-11-29 08:55

    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

    0 讨论(0)
  • 2020-11-29 08:58

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

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

     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.

    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool DeleteObject(IntPtr value);
    
    0 讨论(0)
提交回复
热议问题