CXTPImageManager::ResampleAlphaLayer Correction
Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=18822
Printed Date: 18 June 2025 at 11:12pm Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com
Topic: CXTPImageManager::ResampleAlphaLayer Correction
Posted By: tomay3000
Subject: CXTPImageManager::ResampleAlphaLayer Correction
Date Posted: 12 August 2011 at 9:29pm
Inside .h file //HBITMAP ResampleAlphaLayer(HBITMAP bmpAlpha, COLORREF clrMask = RGB(255, 255, 255));
Inside .cpp file /*HBITMAP ResampleAlphaLayer(HBITMAP bmpAlpha, COLORREF clrMask) { CDC dcSrc; dcSrc.CreateCompatibleDC(NULL); LPBYTE pBits = NULL; LPBITMAPINFO pBitmapInfo = NULL; UINT nSize; if (!CXTPImageManagerIcon::GetBitmapBits(dcSrc, bmpAlpha, pBitmapInfo, (LPVOID&)pBits, nSize)) return NULL; LPBYTE pTarget = NULL; LPBYTE pSource = pBits; pBitmapInfo->bmiHeader.biBitCount = 24; pBitmapInfo->bmiHeader.biSizeImage = 0; pBitmapInfo->bmiHeader.biCompression = BI_RGB; HBITMAP hBitmapResult = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (LPVOID*)&pTarget, NULL, 0); if (pTarget && pSource && hBitmapResult) { for (int i = 0; i < pBitmapInfo->bmiHeader.biHeight; i ++) { for (int j = 0; j < pBitmapInfo->bmiHeader.biWidth; j ++) { BYTE bytAlpha = pSource[3]; if (bytAlpha == 0) // Transparent { pTarget[0] = GetBValue(clrMask); pTarget[1] = GetGValue(clrMask); pTarget[2] = GetRValue(clrMask); } else if (bytAlpha == 255) // Opaque { pTarget[0] = pSource[0]; pTarget[1] = pSource[1]; pTarget[2] = pSource[2]; } else // Semitransparent { pTarget[0] = (BYTE)(abs(GetBValue(clrMask) - pSource[0]) * (255 - bytAlpha) / 255); pTarget[1] = (BYTE)(abs(GetGValue(clrMask) - pSource[1]) * (255 - bytAlpha) / 255); pTarget[2] = (BYTE)(abs(GetRValue(clrMask) - pSource[2]) * (255 - bytAlpha) / 255); } pTarget += 3; pSource += 4; } if (pBitmapInfo->bmiHeader.biWidth % 2) pTarget ++; } } FREE(pBits); FREE(pBitmapInfo); return hBitmapResult; }*/

------------- Product: Codejock ToolkitPro MFC v16.2.0 Platform: Microsoft Windows 8 Pro (64-bit)
Language: Microsoft Visual C++ v6.0 (MFC)
|
Replies:
Posted By: Oleg
Date Posted: 15 August 2011 at 2:51am
Thanks, actually Resample is obsolete function now - was added when ImageManager didn't support alpha images in Win9x. Now you can draw alpha bitmap in all OS, so you don't need call Resample.
------------- Oleg, Support Team CODEJOCK SOFTWARE SOLUTIONS
|
Posted By: tomay3000
Date Posted: 15 August 2011 at 2:24pm
Oleg wrote:
Thanks, actually Resample is obsolete function now - was added when ImageManager didn't support alpha images in Win9x. Now you can draw alpha bitmap in all OS, so you don't need call Resample. |
I think you are wrong about this. The problem depends on the printer capability. Because some printer devices doesn't support alpha-blending, so the use of
CXTPImageManager::ResampleAlphaLayer
is still needed. I have faced this problem when printing on an A4 paper.

------------- Product: Codejock ToolkitPro MFC v16.2.0 Platform: Microsoft Windows 8 Pro (64-bit)
Language: Microsoft Visual C++ v6.0 (MFC)
|
Posted By: Oleg
Date Posted: 24 August 2011 at 8:41am
Hi,
Thanks, I see. Will review this code.
------------- Oleg, Support Team CODEJOCK SOFTWARE SOLUTIONS
|
Posted By: tomay3000
Date Posted: 24 August 2011 at 8:46pm
Oleg wrote:
Hi,
Thanks, I see. Will review this code. |
welcome
------------- Product: Codejock ToolkitPro MFC v16.2.0 Platform: Microsoft Windows 8 Pro (64-bit)
Language: Microsoft Visual C++ v6.0 (MFC)
|
Posted By: tomay3000
Date Posted: 13 September 2011 at 2:33pm
Oleg wrote:
Hi,
Thanks, I see. Will review this code. |
I have seen your code in CXTPImageManager::ResampleAlphaLayer function of the Codejock ToolkitPro MFC v15.1.3.0908 & this is what I would like to say:
First: This is the true, global & final math formula used in re-sampling 32bit alpha bitmaps to 24bit bitmaps. I have been working last night to find it.

Second:
In your code you used this: pTarget[0] = (BYTE)((pSource[0] * (255 - iAlpha) + pSource[0] * iAlpha) >> 8); pTarget[1] = (BYTE)((pSource[1] * (255 - iAlpha) + pSource[1] * iAlpha) >> 8); pTarget[2] = (BYTE)((pSource[2] * (255 - iAlpha) + pSource[2] * iAlpha) >> 8);
And as known:
(x * y) + (x * z) = x * (y + z)
So, your code is the same as the below:
pTarget[0] = (BYTE)((pSource[0] * 255) >> 8); pTarget[1] = (BYTE)((pSource[1] * 255) >> 8); pTarget[2] = (BYTE)((pSource[2] * 255) >> 8);
Third:
R G B & A values of a bitmap are stored in like this: BGRA BGRA BGRA BGRA BGRA ... and not RGBA as you did. (You confused Red with Blue).
Fourth:
This is the last CXTPImageManager::ResampleAlphaLayer function that should be:
HBITMAP CXTPImageManager::ResampleAlphaLayer(HBITMAP hBitmapAlpha, COLORREF clrMask) { LPBYTE lpbytBits = NULL; LPBITMAPINFO lpBitmapInfo = NULL; UINT uiSize; if (!CXTPImageManagerIcon::GetBitmapBits(*CDC::FromHandle(::CreateCompatibleDC(NULL)), hBitmapAlpha, lpBitmapInfo, (LPVOID&)lpbytBits, uiSize)) return NULL; LPBYTE lpbytTarget = NULL; LPBYTE lpbytSource = lpbytBits; lpBitmapInfo->bmiHeader.biBitCount = 24; lpBitmapInfo->bmiHeader.biCompression = BI_RGB; lpBitmapInfo->bmiHeader.biSizeImage = 0; HBITMAP hBitmapResult = ::CreateDIBSection(::CreateCompatibleDC(NULL), lpBitmapInfo, DIB_RGB_COLORS, (LPVOID *)&lpbytTarget, NULL, 0); if (lpbytTarget && lpbytSource && hBitmapResult) { for (int i = 0; i < lpBitmapInfo->bmiHeader.biHeight; i ++) { for (int j = 0; j < lpBitmapInfo->bmiHeader.biWidth; j ++) { lpbytTarget[0] = (BYTE)(GetBValue(clrMask) + lpbytSource[3] * (lpbytSource[0] - GetBValue(clrMask)) / 255); lpbytTarget[1] = (BYTE)(GetGValue(clrMask) + lpbytSource[3] * (lpbytSource[1] - GetGValue(clrMask)) / 255); lpbytTarget[2] = (BYTE)(GetRValue(clrMask) + lpbytSource[3] * (lpbytSource[2] - GetRValue(clrMask)) / 255); lpbytTarget += 3; lpbytSource += 4; }
lpbytTarget += -(lpBitmapInfo->bmiHeader.biWidth * 3) & 3; } } FREE(lpbytBits); FREE(lpBitmapInfo); return hBitmapResult; }
Fifth:
This is a result of the comparison of an image and some variable masks. Original Image:

Mask = RGB(255, 255, 255)

Mask = RGB(255, 0, 0)

Mask = RGB(0, 255, 0)

Mask = RGB(0, 0, 255)

& Finally:
Thank you for your understand & PLEASE do this fix in the next hotfix 
------------- Product: Codejock ToolkitPro MFC v16.2.0 Platform: Microsoft Windows 8 Pro (64-bit)
Language: Microsoft Visual C++ v6.0 (MFC)
|
|