Click here to Skip to main content
Click here to Skip to main content
Alternative Tip/Trick

Tagged as

A very basic alpha blend algorithm

, 19 Apr 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
SledgeHammer didn't help, so I had to do it myself... here it is again - a super fast improved algorithm compared to the previous one and with no setpixel and getpixel :)void AlphaBlend(CDC* pDC, int xDest, int yDest, int nDestWidth, int nDestHeight, CDC* pSrcDC, int xSrc, int ySrc, BYTE...
SledgeHammer didn't help, so I had to do it myself... here it is again - a super fast improved algorithm compared to the previous one and with no setpixel and getpixel Smile | :)
 
void AlphaBlend(CDC* pDC, int xDest, int yDest, int nDestWidth, int nDestHeight,
   CDC* pSrcDC, int xSrc, int ySrc, BYTE uAlphaValue)
{
    ASSERT(pDC);
 
    BOOL bProceed = TRUE;
 
    CDC memDC;
    if(!memDC.CreateCompatibleDC(pDC))
    {
        bProceed = FALSE;
    }
 
    CBitmap memBmp;
    if(bProceed)
    {
        if(!memBmp.CreateCompatibleBitmap(pDC, nDestWidth, nDestHeight))
        {
            bProceed = FALSE;
        }
    }
 
    if(bProceed)
    {
        CBitmap* pOldBmp = memDC.SelectObject(&memBmp);
 
        memDC.BitBlt(0, 0, nDestWidth, nDestHeight, pDC, 0, 0, SRCCOPY);
 
        int nColorSize = sizeof(COLORREF);
        DWORD dwSize = nDestWidth * nDestHeight * nColorSize;
        BYTE* pBitmapBits = new BYTE [dwSize];
        if(!pBitmapBits || 
               memBmp.GetBitmapBits(dwSize,  pBitmapBits) <= 0)
        {
            memDC.SelectObject(pOldBmp);
            if(pBitmapBits)
            {
                delete[] pBitmapBits;
            }
 
            return;
        }
        COLORREF* pBits = (COLORREF*)pBitmapBits;
 
        CBitmap tempBmp;
        tempBmp.CreateCompatibleBitmap(pDC, nDestWidth, nDestHeight);
        CBitmap* pSrcBitmap = pSrcDC->SelectObject(&tempBmp);
        BYTE* pSrcBitmapBits = new BYTE [dwSize];
        if(!pSrcBitmapBits  
         || pSrcBitmap->GetBitmapBits(dwSize,  pSrcBitmapBits) <= 0)
        {
            pSrcDC->SelectObject(pSrcBitmap);
            if(pSrcBitmapBits)
            {
                delete[] pSrcBitmapBits;
            }
 
            return;
        }
        COLORREF* pSrcBits = (COLORREF*)pSrcBitmapBits;
 
        pSrcDC->SelectObject(pSrcBitmap);
 
        CDC* pDestDC = &memDC;
 
        ASSERT(pDestDC);
        ASSERT(pSrcDC);
 
        BYTE r1, r2, rDest;
        BYTE g1, g2, gDest;
        BYTE b1, b2, bDest;
 
        BYTE av = uAlphaValue; // Alpha value BYTE

        BYTE rem = 255 - av; // Remaining fraction

        COLORREF clrPixelDest;
        COLORREF clrPixelSrc;
 
        for(int dy = yDest, sy = ySrc; dy < nDestHeight; dy++, sy++)
        {
            for(int dx = xDest, sx = xSrc; dx < nDestWidth; dx++, sx++)
            {
                clrPixelDest = pBits[dy * nDestWidth + dx];
 
                // The bitmap is in reverse order (bottom to top)
                // so the RGBs are in reverse order
                b1 = GetRValue(clrPixelDest);
                g1 = GetGValue(clrPixelDest);
                r1 = GetBValue(clrPixelDest);
 
                clrPixelSrc = pSrcBits[sy * nDestWidth + sx];
 
                // The bitmap is in reverse order (bottom to top) 
                // so the RGBs are in reverse order
                b2 = GetRValue(clrPixelSrc);
                g2 = GetGValue(clrPixelSrc);
                r2 = GetBValue(clrPixelSrc);
 
                rDest = (r1*rem + r2*av) / 255;
                gDest = (g1*rem + g2*av) / 255;
                bDest = (b1*rem + b2*av) / 255;
 
                // The bitmap is in reverse order (bottom to top) 
                //so the RGBs will be in reverse order
                pBits[dy * nDestWidth + dx] = RGB(bDest, gDest, rDest);
            }
        }
 
        memBmp.SetBitmapBits(dwSize, pBits);
        pDC->BitBlt(0, 0, nDestWidth, nDestHeight, &memDC, 0, 0, SRCCOPY);
 
        memDC.SelectObject(pOldBmp);
 
        delete[] pBitmapBits;
        delete[] pSrcBitmapBits;
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mukit, Ataul
Chief Technology Officer Rational Technologies
Bangladesh Bangladesh
C++ is not C with classes, JQuery is not Javascript, Google Search is not Learning, Design Patterns are not fashion, A code written in 2005 is not backdated just because it's 2015
Follow on   Twitter

Comments and Discussions

 
GeneralRe: Darn!! I missed that delete pBitmapBits part, thanx..!! Code... PinmemberMukit, Ataul20-Apr-11 23:52 
GeneralRe: Most code can be rewritten to be faster. But almost always, ... PinmemberNiklas Lindquist20-Apr-11 22:01 
GeneralRe: Not sure whether changin the alpha value is a good solution.... PinmemberMukit, Ataul19-Apr-11 21:19 
GeneralRe: yes, it's a division by 256. try: int av = uAlphaValue + 1;... Pinmemberollienator19-Apr-11 20:50 
GeneralRe: I think >> 8 means division by 256 and not 255. Can anybody ... PinmemberMukit, Ataul19-Apr-11 19:40 
GeneralRe: You can unroll the nested loops and just treat them as a con... Pinmemberbasementman14-Apr-11 6:05 
GeneralRe: as mentioned in your point 4 - "Reordering when necessary mi... PinmemberMukit, Ataul12-Apr-11 1:49 
GeneralRe: You're welcome! PinmvpManfred R. Bihy13-Apr-11 11:17 
GeneralI would not worry about people claiming there will be cache ... PinmemberNiklas Lindquist20-Apr-11 2:34 
GeneralRe: Thanx.. that was really inpiring PinmemberMukit, Ataul20-Apr-11 19:52 
GeneralRe: Hoi, I have to contradict here a lot. Go use, for instance, ... Pinmembergilgamash20-Sep-11 23:06 
GeneralReason for my vote of 5 Fast and simple thanks. Pinmemberarm2arm119-Apr-11 0:23 
GeneralRe: my pleasure.. PinmemberMukit, Ataul19-Apr-11 0:25 
GeneralThis short paper explains it well and thoroughly: http://sy... Pinmembergilgamash12-Apr-11 2:36 
GeneralYou can make it still faster: 1) Replace the divisions by ... Pinmembergilgamash12-Apr-11 1:29 
GeneralRe: All i can say is "WOW!!" .. Thnx... it mite really help in f... PinmemberMukit, Ataul12-Apr-11 1:43 
GeneralRe: why not replace /255 with >>8 ? Pinmemberollienator19-Apr-11 7:26 
GeneralReason for my vote of 5 Nice! PinmvpManfred R. Bihy11-Apr-11 4:39 
GeneralRe: Finally some appreciation.. thanx :) PinmemberMukit, Ataul11-Apr-11 22:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 19 Apr 2011
Article Copyright 2011 by Mukit, Ataul
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid