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