抖音色度抠图代码
void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart, short yStart, COLORREF cTransparentColor)
{ // 色度摳圖: 把hBitmap中的顏色cTransparentColor替換成透明色,并寫到hdc上// hdc 顯示句柄
// hBitmap 要顯示的位圖
// xStart,xStart 顯示的位置
// xadd,yadd 顯示的位圖的大小變化:放大縮小
// 如:xadd=3 表示位圖寬度加 3
// cTransparentColor 變成透明的那種顏色BITMAP bm; COLORREF cColor; HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave; HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; POINT ptSize; hdcTemp = CreateCompatibleDC(hdc); SelectObject(hdcTemp, hBitmap); // Select the bitmap GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); ptSize.x = bm.bmWidth; // Get width of bitmap ptSize.y = bm.bmHeight; // Get height of bitmap DPtoLP(hdcTemp, &ptSize, 1); // Convert from device // to logical points // Create some DCs to hold temporary data. hdcBack = CreateCompatibleDC(hdc); hdcObject = CreateCompatibleDC(hdc); hdcMem = CreateCompatibleDC(hdc); hdcSave = CreateCompatibleDC(hdc); // Create a bitmap for each DC. DCs are required for a number of // GDI functions. // Monochrome DC bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); // Monochrome DC bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); // Each DC must select a bitmap object to store pixel data. bmBackOld = (HBITMAP)SelectObject(hdcBack, bmAndBack); bmObjectOld =(HBITMAP)SelectObject(hdcObject, bmAndObject); bmMemOld = (HBITMAP)SelectObject(hdcMem, bmAndMem); bmSaveOld = (HBITMAP)SelectObject(hdcSave, bmSave); // Set proper mapping mode. SetMapMode(hdcTemp, GetMapMode(hdc)); // Save the bitmap sent here, because it will be overwritten. BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); // Set the background color of the source DC to the color. // contained in the parts of the bitmap that should be transparent cColor = SetBkColor(hdcTemp, cTransparentColor); // Create the object mask for the bitmap by performing a BitBlt // from the source bitmap to a monochrome bitmap. BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); // Set the background color of the source DC back to the original // color. SetBkColor(hdcTemp, cColor); // Create the inverse of the object mask. BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY); // Copy the background of the main DC to the destination. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY); // Mask out the places where the bitmap will be placed. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); // Mask out the transparent colored pixels on the bitmap. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); // XOR the bitmap with the background on the destination DC. BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); // Copy the destination to the screen. BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY); // Place the original bitmap back into the bitmap sent here. BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); // Delete the memory bitmaps. DeleteObject(SelectObject(hdcBack, bmBackOld)); DeleteObject(SelectObject(hdcObject, bmObjectOld)); DeleteObject(SelectObject(hdcMem, bmMemOld)); DeleteObject(SelectObject(hdcSave, bmSaveOld)); // Delete the memory DCs. DeleteDC(hdcMem); DeleteDC(hdcBack); DeleteDC(hdcObject); DeleteDC(hdcSave); DeleteDC(hdcTemp);
}
?
?
void TransparentBitmap(HDC hdc, HBITMAP hBitmap,short xStart,short yStart, short xadd,short yadd, COLORREF cTransparentColor) { //// 色度摳圖: 本函數把一種指定的顏色變成透明色,并可改變大小// hdc 顯示句柄// hBitmap 要顯示的位圖// xStart,xStart 顯示的位置// xadd,yadd 顯示的位圖的大小變化:放大縮小// 如:xadd=3 表示位圖寬度加 3// cTransparentColor 要被替換成透明的顏色//BITMAP m_bm;COLORREF cColor;// 創建臨時 DCHDC hMem, hBack, hObject, hTemp, hSave;hBack = CreateCompatibleDC(hdc); hObject = CreateCompatibleDC(hdc); hMem = CreateCompatibleDC(hdc); hSave = CreateCompatibleDC(hdc); hTemp = CreateCompatibleDC(hdc);// 選入位圖SelectObject(hTemp, hBitmap);GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&m_bm);//顯示位圖寬高POINT ptSize;// 取得位圖的寬度ptSize.x = m_bm.bmWidth;// 取得位圖的該度ptSize.y = m_bm.bmHeight;// 轉換為邏輯點值DPtoLP(hTemp, &ptSize, 1);// 創建臨時位圖HBITMAP bmBack, bmObject, bmMem, bmSave;// 單色位圖bmBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);bmObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);// 與設備兼容位圖bmMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);// 將創建的臨時位圖選入臨時 DC 中HBITMAP OldbmBack, OldbmObject, OldbmMem, OldbmSave; OldbmBack = (HBITMAP)SelectObject(hBack, bmBack); OldbmObject = (HBITMAP)SelectObject(hObject, bmObject); OldbmMem = (HBITMAP)SelectObject(hMem, bmMem); OldbmSave = (HBITMAP)SelectObject(hSave, bmSave);// 設置映射模式SetMapMode(hTemp, GetMapMode(hdc));// 先保留原始位圖BitBlt(hSave, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);// 將背景顏色設置為需透明的顏色cColor = SetBkColor(hTemp, cTransparentColor);// 創建目標屏蔽碼BitBlt(hObject, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);// 恢復源 DC 的原始背景色SetBkColor(hTemp, cColor);// 創建反轉的目標屏蔽碼BitBlt(hBack, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, NOTSRCCOPY);// 拷貝主 DC 的背景到目標 DCBitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);// 屏蔽位圖的顯示區BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, SRCAND);// 屏蔽位圖中的透明色BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hBack, 0, 0, SRCAND);// 將位圖與目標 DC 的背景左異或操作BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCPAINT);// 拷貝目標到屏幕上StretchBlt(hdc, xStart, yStart, ptSize.x+xadd, ptSize.y+yadd, hMem, 0, 0, ptSize.x, ptSize.y, SRCCOPY);// 恢復原始位圖BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hSave, 0, 0, SRCCOPY);// 刪除臨時內存位圖 DeleteObject(SelectObject(hBack, OldbmBack)); DeleteObject(SelectObject(hObject, OldbmObject)); DeleteObject(SelectObject(hMem, OldbmMem)); DeleteObject(SelectObject(hSave, OldbmSave));// 刪除臨時內存 DCDeleteDC(hMem); DeleteDC(hBack); DeleteDC(hObject); DeleteDC(hSave); DeleteDC(hTemp); }?
總結
- 上一篇: Kaldi内存泄漏问题排查
- 下一篇: (转)探究 TCP 一次数据包最大负载,