首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

GDI 與 GDI+ 物件互轉實戰技巧全解析

     編輯:關於VC++

前言:新舊共存的現實妥協

理想狀態下,GDI+ 完全取代 GDI;次佳情況僅需單向轉換。但現實專案常面臨「要新特性、要快速開發、又不捨棄舊代碼」的三重壓力,唯有掌握雙向互轉技巧,才能在遷移期平穩過渡。

核心互轉場景與代碼模式

一、CDC → Graphics (最常用、最簡單)

Graphics g(pDC->GetSafeHdc());
// 任何能構造 CDC 指標的 MFC 物件皆適用:CClientDC、CPaintDC 等

二、CBitmap → Graphics (需建立記憶體 DC)

CDC MemDC;
CBitmap MemBitmap;
MemDC.CreateCompatibleDC(pDC);
MemBitmap.CreateCompatibleBitmap(pDC, size.cx, size.cy);
CBitmap* pOldBit = MemDC.SelectObject(&MemBitmap);
Graphics g(MemDC.GetSafeHdc());
// ... 使用 GDI+ 繪圖 ...
MemDC.SelectObject(pOldBit); // 恢復原位圖

替代方案:Bitmap::FromHBITMAP(HBITMAP, HPALETTE) 靜態方法直接建立 GDI+ Bitmap。

三、GDI+ Bitmap → CBitmap (歷史代碼整合常見需求)

Bitmap* pPicture = new Bitmap(L"dotLive.jpg");
HBITMAP hBitmap;
pPicture->GetHBITMAP(Color(0,0,0), &hBitmap); // 背景色設為黑色
CBitmap* pbm = CBitmap::FromHandle(hBitmap);
// ... 使用 pbm 進行 GDI 操作 ...
pbm->DeleteObject(); // 必須釋放 GDI 物件,否則記憶體洩漏

四、Bitmap 儲存檔案:解決檔案鎖定衝突

痛點:Bitmap/Image 開啟圖片會鎖定檔案,直接 Save 同名檔案會報「檔案被使用」錯誤。
解法:建立新 Bitmap 複製內容,刪除舊物件釋放鎖定,再儲存新物件。不可用 Clone(),它會連同鎖定資源一起複製。

Bitmap* tPic = new Bitmap(L"dotLive.jpg"); // 鎖定檔案
Bitmap* pPicture = new Bitmap(tPic->GetWidth(), tPic->GetHeight(), tPic->GetPixelFormat());
Graphics g(pPicture);
g.DrawImage(tPic, 0, 0, m_nWidth, m_nHeight); // 複製像素資料
delete tPic; // 釋放鎖定

// ... 對 pPicture 進行操作 ...

CLSID tiffClsid;
GetEncoderClsid(L"image/jpeg", &tiffClsid); // MSDN 有此函數實現
pPicture->Save(L"dotLive.jpg", &tiffClsid); // 成功儲存

五、Graphics → HDC (GDI+ 載圖 + GDI 繪文字/橡皮筋)

場景:GDI+ 載圖方便,但缺異或模式 (橡皮筋)、文字輸出無背景透明控制、字串需轉 WCHAR。需獲取 HDC 使用 GDI 函數。

Bitmap* pPicture = new Bitmap(L"dotLive.jpg");
Graphics tempG(pPicture);
HDC hdc = tempG.GetHDC();          // 獲取 GDI 相容 DC
CDC* tempDC = CDC::FromHandle(hdc);
// ... 瘋狂呼叫 GDI 函數: TextOut, MoveTo, LineTo, SetROP2(R2_NOTXORPEN) ...
tempG.ReleaseHDC(hdc);             // 必須 Release,否則資源佔用阻塞後續操作

關鍵提醒

  • 資源釋放鐵律:GetHDC() 必配 ReleaseHDC();SelectObject() 必配還原原物件;new 配置必配 delete。
  • 像素格式一致性:建立新 Bitmap 複製時,保持 GetPixelFormat() 一致。
  • 編碼器選擇:儲存時需正確獲取 CLSID (如 image/jpeg、image/png)。

歡迎探討 GDI+、影像處理與 .NET 程式設計相關技術。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved