Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Toolkit Pro
  New Posts New Posts RSS Feed - CXTPImageManager::ResampleAlphaLayer Correction
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

CXTPImageManager::ResampleAlphaLayer Correction

 Post Reply Post Reply
Author
Message
tomay3000 View Drop Down
Groupie
Groupie
Avatar

Joined: 08 December 2010
Location: Algeria
Status: Offline
Points: 56
Post Options Post Options   Thanks (0) Thanks(0)   Quote tomay3000 Quote  Post ReplyReply Direct Link To This Post Topic: CXTPImageManager::ResampleAlphaLayer Correction
    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)
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post 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
Back to Top
tomay3000 View Drop Down
Groupie
Groupie
Avatar

Joined: 08 December 2010
Location: Algeria
Status: Offline
Points: 56
Post Options Post Options   Thanks (0) Thanks(0)   Quote tomay3000 Quote  Post ReplyReply Direct Link To This Post 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)
Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 24 August 2011 at 8:41am
Hi,

Thanks, I see. Will review this code.
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
tomay3000 View Drop Down
Groupie
Groupie
Avatar

Joined: 08 December 2010
Location: Algeria
Status: Offline
Points: 56
Post Options Post Options   Thanks (0) Thanks(0)   Quote tomay3000 Quote  Post ReplyReply Direct Link To This Post 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)
Back to Top
tomay3000 View Drop Down
Groupie
Groupie
Avatar

Joined: 08 December 2010
Location: Algeria
Status: Offline
Points: 56
Post Options Post Options   Thanks (0) Thanks(0)   Quote tomay3000 Quote  Post ReplyReply Direct Link To This Post 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)
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.063 seconds.