inline void __stdcall SetAlphaPixel(COLORREF* pBits, int rect_Width, int rect_Height, int x, int y, int percent, int iShadowSize, COLORREF clrBase, BOOL bIsRight) { // Our direct bitmap access swapped the y coordinate... y = (rect_Height + iShadowSize) - y; COLORREF* pColor = (COLORREF*)(bIsRight ? (pBits + (rect_Width + iShadowSize) * (y + 1) - x) : (pBits + (rect_Width + iShadowSize) * y + x)); *pColor = PixelAlpha(*pColor, percent); if (clrBase == (COLORREF) - 1) { return; } *pColor = RGB(min(255, (3 * GetRValue(*pColor) + GetBValue(clrBase)) / 4), min(255, (3 * GetGValue(*pColor) + GetGValue(clrBase)) / 4), min(255, (3 * GetBValue(*pColor) + GetRValue(clrBase)) / 4)); }
BOOL WINAPI AlphaBitBlt(HDC hDC, int nDestX, int nDestY, int dwWidth, int dwHeight, HDC hSrcDC, int nSrcX, int nSrcY, int wSrc, int hSrc, BLENDFUNCTION ftn) { HDC hTempDC = ::CreateCompatibleDC(hDC); if (NULL == hTempDC) return FALSE; //Creates Source DIB LPBITMAPINFO lpbiSrc = NULL; // Fill in the BITMAPINFOHEADER lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; if (lpbiSrc == NULL) { ::DeleteDC(hTempDC); return FALSE; } lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiSrc->bmiHeader.biWidth = dwWidth; lpbiSrc->bmiHeader.biHeight = dwHeight; lpbiSrc->bmiHeader.biPlanes = 1; lpbiSrc->bmiHeader.biBitCount = 32; lpbiSrc->bmiHeader.biCompression = BI_RGB; lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiSrc->bmiHeader.biXPelsPerMeter = 0; lpbiSrc->bmiHeader.biYPelsPerMeter = 0; lpbiSrc->bmiHeader.biClrUsed = 0; lpbiSrc->bmiHeader.biClrImportant = 0; COLORREF* pSrcBits = NULL; HBITMAP hSrcDib = CreateDIBSection( hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits, NULL, NULL); if ((NULL == hSrcDib) || (NULL == pSrcBits)) { delete[] lpbiSrc; ::DeleteDC(hTempDC); return FALSE; } HBITMAP hOldTempBmp = (HBITMAP)::SelectObject(hTempDC, hSrcDib); ::StretchBlt(hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, wSrc, hSrc, SRCCOPY); ::SelectObject(hTempDC, hOldTempBmp); //Creates Destination DIB LPBITMAPINFO lpbiDest = NULL; // Fill in the BITMAPINFOHEADER lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; if (lpbiDest == NULL) { delete[] lpbiSrc; ::DeleteObject(hSrcDib); ::DeleteDC(hTempDC); return FALSE; } lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiDest->bmiHeader.biWidth = dwWidth; lpbiDest->bmiHeader.biHeight = dwHeight; lpbiDest->bmiHeader.biPlanes = 1; lpbiDest->bmiHeader.biBitCount = 32; lpbiDest->bmiHeader.biCompression = BI_RGB; lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiDest->bmiHeader.biXPelsPerMeter = 0; lpbiDest->bmiHeader.biYPelsPerMeter = 0; lpbiDest->bmiHeader.biClrUsed = 0; lpbiDest->bmiHeader.biClrImportant = 0; COLORREF* pDestBits = NULL; HBITMAP hDestDib = CreateDIBSection( hDC, lpbiDest, DIB_RGB_COLORS, (void **)&pDestBits, NULL, NULL); if ((NULL == hDestDib) || (NULL == pDestBits)) { delete[] lpbiSrc; ::DeleteObject(hSrcDib); ::DeleteDC(hTempDC); return FALSE; } //这段用来绘制透明背景? ::SelectObject(hTempDC, hDestDib); ::BitBlt(hTempDC, 0, 0, dwWidth, dwHeight, hDC, nDestX, nDestY, SRCCOPY); ::SelectObject(hTempDC, hOldTempBmp); double src_darken; BYTE nAlpha; for (int pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++) { nAlpha = LOBYTE(*pSrcBits >> 24); if (nAlpha > 0) nAlpha++; src_darken = (double)(nAlpha * ftn.SourceConstantAlpha) / 255.0 / 255.0; if (src_darken < 0.0) src_darken = 0.0; *pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, 1.0 - src_darken); } //for ::SelectObject(hTempDC, hDestDib); ::BitBlt(hDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY); ::SelectObject(hTempDC, hOldTempBmp); delete[] lpbiDest; ::DeleteObject(hDestDib); delete[] lpbiSrc; ::DeleteObject(hSrcDib); ::DeleteDC(hTempDC); return TRUE; }
void CPPDrawManager::AlphaBitBlt(HDC hDestDC, int nDestX, int nDestY, DWORD dwWidth, DWORD dwHeight, HDC hSrcDC, int nSrcX, int nSrcY, int percent /* = 100 */) { _ASSERT ((NULL != hDestDC) || (NULL != hSrcDC)); if (percent >= 100) { ::BitBlt(hDestDC, nDestX, nDestY, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY); return; } //if HDC hTempDC = ::CreateCompatibleDC(hDestDC); if (NULL == hTempDC) return; //Creates Source DIB LPBITMAPINFO lpbiSrc; // Fill in the BITMAPINFOHEADER lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiSrc->bmiHeader.biWidth = dwWidth; lpbiSrc->bmiHeader.biHeight = dwHeight; lpbiSrc->bmiHeader.biPlanes = 1; lpbiSrc->bmiHeader.biBitCount = 32; lpbiSrc->bmiHeader.biCompression = BI_RGB; lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiSrc->bmiHeader.biXPelsPerMeter = 0; lpbiSrc->bmiHeader.biYPelsPerMeter = 0; lpbiSrc->bmiHeader.biClrUsed = 0; lpbiSrc->bmiHeader.biClrImportant = 0; COLORREF* pSrcBits = NULL; HBITMAP hSrcDib = CreateDIBSection ( hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&pSrcBits, NULL, NULL); if ((NULL != hSrcDib) && (NULL != pSrcBits)) { HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib); ::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); //Creates Destination DIB LPBITMAPINFO lpbiDest; // Fill in the BITMAPINFOHEADER lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)]; lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiDest->bmiHeader.biWidth = dwWidth; lpbiDest->bmiHeader.biHeight = dwHeight; lpbiDest->bmiHeader.biPlanes = 1; lpbiDest->bmiHeader.biBitCount = 32; lpbiDest->bmiHeader.biCompression = BI_RGB; lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight; lpbiDest->bmiHeader.biXPelsPerMeter = 0; lpbiDest->bmiHeader.biYPelsPerMeter = 0; lpbiDest->bmiHeader.biClrUsed = 0; lpbiDest->bmiHeader.biClrImportant = 0; COLORREF* pDestBits = NULL; HBITMAP hDestDib = CreateDIBSection ( hDestDC, lpbiDest, DIB_RGB_COLORS, (void **)&pDestBits, NULL, NULL); if ((NULL != hDestDib) && (NULL != pDestBits)) { ::SelectObject (hTempDC, hDestDib); ::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDestDC, nDestX, nDestY, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); double src_darken = (double)percent / 100.0; double dest_darken = 1.0 - src_darken; for (DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++) { *pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, dest_darken); } //for ::SelectObject (hTempDC, hDestDib); ::BitBlt (hDestDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY); ::SelectObject (hTempDC, hOldTempBmp); delete lpbiDest; ::DeleteObject(hDestDib); } //if delete lpbiSrc; ::DeleteObject(hSrcDib); } //if ::DeleteDC(hTempDC); } //End AlphaBitBlt