C# 图像转换实战:Bitmap 转 BitmapSource 的 2 种方法
- 引言
- 两种转换方法的完整实现
-
- 1. 基于GDI句柄的直接转换 (ToBitmapSourceFast)
- 2. 基于内存流的编码转换 (ToBitmapSourceSafe)
- 方法对比与选型指南
- 避坑指南
-
- GDI句柄泄漏问题
- 图像显示不完整
- 多线程访问图像引发异常
- 不同场景的最佳实践
-
- UI 实时渲染场景(如视频播放器)
- 后台批量处理场景
- 混合策略
- 总结与决策
C# 图像转换实战:Bitmap 转 BitmapSource 的 2 种方法
引言
在 C# 开发中,当你同时使用 Windows Forms 和 WPF 框架时,是否曾遇到过这样的窘境:
- “明明都是表示图像的数据类型,为什么 System.Drawing.Bitmap 不能直接赋值给 WPF 的 Image 控件?”
- “转换图像后程序内存占用飙升,甚至出现莫名其妙的 GDI + 错误?”
这两个问题的根源在于:System.Drawing.Bitmap 属于GDI+(Windows Forms),而 BitmapSource 是WPF核心类型,两者基于不同渲染引擎,无法直接赋值。下面是适用于不同场景下的两种高效转换的方案,解决混合编程中的图像类型转换难题
两种转换方法的完整实现
1. 基于GDI句柄的直接转换 (ToBitmapSourceFast)
[DllImport("gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject);
public static BitmapSource ToBitmapSourceFast(this Bitmap bitmap)
{if (bitmap == null) return null;IntPtr hBitmap = IntPtr.Zero;try{hBitmap = bitmap.GetHbitmap(); // 获取GDI句柄(非托管资源)return Imaging.CreateBitmapSourceFromHBitmap(hBitmap,IntPtr.Zero,System.Windows.Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions()); // 直接从GDI句柄创建BitmapSource}catch (Exception ex){Console