Print Page | Close Window

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;
}*/


Thumbs Up


-------------
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
Originally posted by Oleg 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.
Thumbs Up


-------------
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
Originally posted by Oleg 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
Originally posted by Oleg 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 Wink



-------------
Product: Codejock ToolkitPro MFC v16.2.0
Platform: Microsoft Windows 8 Pro (64-bit)

Language: Microsoft Visual C++ v6.0 (MFC)



Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net