C# – 将WPF Image.source转换为System.Drawing.Bitmap

我发现有很多人将BitmapSource转换为Bitmap ,但是ImageSourceBitmap呢? 我正在制作一个成像程序,我需要从Image元素中显示的图像中提取位图。 有谁知道如何做到这一点?

编辑1:

这是将BitmapImage转换为Bitmap 。 请记住在编译器首选项中设置“unsafe”选项。

 public static System.Drawing.Bitmap BitmapSourceToBitmap(BitmapSource srs) { System.Drawing.Bitmap btm = null; int width = srs.PixelWidth; int height = srs.PixelHeight; int stride = width * ((srs.Format.BitsPerPixel + 7) / 8); byte[] bits = new byte[height * stride]; srs.CopyPixels(bits, stride, 0); unsafe { fixed (byte* pB = bits) { IntPtr ptr = new IntPtr(pB); btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr); } } return btm; } 

接下来是获取BitmapImage

 RenderTargetBitmap targetBitmap = new RenderTargetBitmap( (int)inkCanvas1.ActualWidth, (int)inkCanvas1.ActualHeight, 96d, 96d, PixelFormats.Default); targetBitmap.Render(inkCanvas1); MemoryStream mse = new MemoryStream(); System.Windows.Media.Imaging.BmpBitmapEncoder mem = new BmpBitmapEncoder(); mem.Frames.Add(BitmapFrame.Create(targetBitmap)); mem.Save(mse); mse.Position = 0; BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = mse; bi.EndInit(); 

接下来是转换它:

 Bitmap b = new Bitmap(BitmapSourceToBitmap(bi)); 

实际上你不需要使用不安全的代码。 CopyPixels的重载接受IntPtr:

 public static System.Drawing.Bitmap BitmapSourceToBitmap2(BitmapSource srs) { int width = srs.PixelWidth; int height = srs.PixelHeight; int stride = width * ((srs.Format.BitsPerPixel + 7) / 8); IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(height * stride); srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride); using (var btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr)) { // Clone the bitmap so that we can dispose it and // release the unmanaged memory at ptr return new System.Drawing.Bitmap(btm); } } finally { if (ptr != IntPtr.Zero) Marshal.FreeHGlobal(ptr); } } 

这个例子对我有用:

  public static Bitmap ConvertToBitmap(BitmapSource bitmapSource) { var width = bitmapSource.PixelWidth; var height = bitmapSource.PixelHeight; var stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); var memoryBlockPointer = Marshal.AllocHGlobal(height * stride); bitmapSource.CopyPixels(new Int32Rect(0, 0, width, height), memoryBlockPointer, height * stride, stride); var bitmap = new Bitmap(width, height, stride, PixelFormat.Format32bppPArgb, memoryBlockPointer); return bitmap; } 

你的ImageSource不是BitmapSource吗? 如果您从文件加载图像应该是。

回复你的评论:

听起来他们应该是BitmapSource然后,BitmapSource是ImageSource的子类型。 将ImageSource转换为BitmapSource并按照其中一个博客文章进行操作。

您根本不需要BitmapSourceToBitmap方法。 创建内存流后,请执行以下操作:

 mem.Position = 0; Bitmap b = new Bitmap(mem);