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

透明位圖繪製原理與 TransparentBlt 手工實作

     編輯:關於VC++

系統 API:TransparentBlt

Windows 98/2000 以上提供 TransparentBlt(需連結 Msimg32.lib),參數包含目標/來源 DC、座標、尺寸與透明色。但 Win98 存在資源洩漏,建議僅在 Win2000+ 使用。

核心原理:掩碼位圖與光柵運算

透明繪製分四步,利用單色掩碼位圖(1-bit)配合 SRCAND、SRCPAINT 等光柵運算碼:

  1. 建立掩碼:將來源 DC 背景色設為透明色,BitBlt 複製至單色 DC → 透明區變白(1),非透明變黑(0)。
  2. 處理前景圖:設背景黑/前景白,以 SRCAND 將掩碼套用至來源圖 → 透明區變黑,其餘保留。
  3. 處理背景圖:設背景白/前景黑,以 SRCAND 將掩碼套用至目標 DC → 透明區保留背景,非透明區變黑。
  4. 合成:以 SRCPAINT (OR 運算) 將前景圖疊加至背景 → 完成透明合成。

完整實作:TransparentBlt2

void TransparentBlt2(HDC hdcDest, int xDest, int yDest, int wDest, int hDest,
                     HDC hdcSrc, int xSrc, int ySrc, int wSrc, int hSrc,
                     UINT crTransparent) {
    HDC hImageDC = CreateCompatibleDC(hdcDest), hMaskDC = CreateCompatibleDC(hdcDest);
    HBITMAP hImageBMP = CreateCompatibleBitmap(hdcDest, wDest, hDest);
    HBITMAP hMaskBMP  = CreateBitmap(wDest, hDest, 1, 1, NULL);
    HBITMAP hOldImg = (HBITMAP)SelectObject(hImageDC, hImageBMP);
    HBITMAP hOldMsk = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

    // 縮放複製來源圖至暫存 DC
    if (wDest == wSrc && hDest == hSrc)
        BitBlt(hImageDC, 0, 0, wDest, hDest, hdcSrc, xSrc, ySrc, SRCCOPY);
    else
        StretchBlt(hImageDC, 0, 0, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, SRCCOPY);

    // 1. 產生掩碼
    SetBkColor(hImageDC, crTransparent);
    BitBlt(hMaskDC, 0, 0, wDest, hDest, hImageDC, 0, 0, SRCCOPY);

    // 2. 前景圖:透明區變黑
    SetBkColor(hImageDC, RGB(0,0,0)); SetTextColor(hImageDC, RGB(255,255,255));
    BitBlt(hImageDC, 0, 0, wDest, hDest, hMaskDC, 0, 0, SRCAND);

    // 3. 背景:非透明區變黑
    SetBkColor(hdcDest, RGB(255,255,255)); SetTextColor(hdcDest, RGB(0,0,0));
    BitBlt(hdcDest, xDest, yDest, wDest, hDest, hMaskDC, 0, 0, SRCAND);

    // 4. 合成
    BitBlt(hdcDest, xDest, yDest, wDest, hDest, hImageDC, 0, 0, SRCPAINT);

    // 清理
    SelectObject(hImageDC, hOldImg); DeleteDC(hImageDC); DeleteObject(hImageBMP);
    SelectObject(hMaskDC, hOldMsk);  DeleteDC(hMaskDC);  DeleteObject(hMaskBMP);
}

進階版:TransparentBltU (支援縮放)

Christian Graus 的版本額外處理來源/目標尺寸不同的情況,建立縮放後的掩碼與圖像 DC,流程同理但更通用。實際專案建議直接呼叫系統 TransparentBlt,本文旨在說明底層原理。

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