我有一个System.Drawing.Bitmap实例,并希望将其以system . windows . media . image . bitmapimage的形式提供给我的WPF应用程序。
最好的方法是什么?
我有一个System.Drawing.Bitmap实例,并希望将其以system . windows . media . image . bitmapimage的形式提供给我的WPF应用程序。
最好的方法是什么?
当前回答
我的观点来自于一些资源。https://stackoverflow.com/a/7035036 https://stackoverflow.com/a/1470182/360211
using System;
using System.Drawing;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using Microsoft.Win32.SafeHandles;
namespace WpfHelpers
{
public static class BitmapToBitmapSource
{
public static BitmapSource ToBitmapSource(this Bitmap source)
{
using (var handle = new SafeHBitmapHandle(source))
{
return Imaging.CreateBitmapSourceFromHBitmap(handle.DangerousGetHandle(),
IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
private sealed class SafeHBitmapHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[SecurityCritical]
public SafeHBitmapHandle(Bitmap bitmap)
: base(true)
{
SetHandle(bitmap.GetHbitmap());
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return DeleteObject(handle) > 0;
}
}
}
}
其他回答
最简单的方法是直接从文件中生成WPF位图。
否则你将不得不使用system . windows . interop . image . createbitmapsourcefromhbitmap。
// at class level;
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject); // https://stackoverflow.com/a/1546121/194717
/// <summary>
/// Converts a <see cref="System.Drawing.Bitmap"/> into a WPF <see cref="BitmapSource"/>.
/// </summary>
/// <remarks>Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
/// </remarks>
/// <param name="source">The source bitmap.</param>
/// <returns>A BitmapSource</returns>
public static System.Windows.Media.Imaging.BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
{
var hBitmap = source.GetHbitmap();
var result = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, System.Windows.Int32Rect.Empty, System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
DeleteObject(hBitmap);
return result;
}
我在一家图像供应商工作,写了一个WPF到我们的图像格式的适配器,它类似于System.Drawing.Bitmap。
我写了这个KB来向我们的客户解释:
http://www.atalasoft.com/kb/article.aspx?id=10156
这里有代码可以做到这一点。你需要用Bitmap替换AtalaImage,并做与我们正在做的相同的事情——这应该是相当简单的。
我来到这个问题,因为我试图做同样的事情,但在我的情况下,位图是来自资源/文件。我发现最好的解决方案如下所示:
http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.aspx
// Create the image element.
Image simpleImage = new Image();
simpleImage.Width = 200;
simpleImage.Margin = new Thickness(5);
// Create source.
BitmapImage bi = new BitmapImage();
// BitmapImage.UriSource must be in a BeginInit/EndInit block.
bi.BeginInit();
bi.UriSource = new Uri(@"/sampleImages/cherries_larger.jpg",UriKind.RelativeOrAbsolute);
bi.EndInit();
// Set the image source.
simpleImage.Source = bi;
我的观点来自于一些资源。https://stackoverflow.com/a/7035036 https://stackoverflow.com/a/1470182/360211
using System;
using System.Drawing;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media.Imaging;
using Microsoft.Win32.SafeHandles;
namespace WpfHelpers
{
public static class BitmapToBitmapSource
{
public static BitmapSource ToBitmapSource(this Bitmap source)
{
using (var handle = new SafeHBitmapHandle(source))
{
return Imaging.CreateBitmapSourceFromHBitmap(handle.DangerousGetHandle(),
IntPtr.Zero, Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
}
}
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
private sealed class SafeHBitmapHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[SecurityCritical]
public SafeHBitmapHandle(Bitmap bitmap)
: base(true)
{
SetHandle(bitmap.GetHbitmap());
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return DeleteObject(handle) > 0;
}
}
}
}