Click here to Skip to main content
11,481,838 members (65,154 online)
Click here to Skip to main content

Tagged as

A very basic alpha blend algorithm

, 19 Apr 2011 CPOL 7.6K 3
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
Your Lord does not like people who waste by extravagance, and only the righteous C s, and does so in increments, and they are of those people who are mindful of what memory and time has in offer and they waste none of it.
Follow on   Twitter

Comments and Discussions

 
GeneralRe: Darn!! I missed that delete pBitmapBits part, thanx..!! Code... Pin
Mukit, Ataul20-Apr-11 23:52
memberMukit, Ataul20-Apr-11 23:52 
GeneralRe: Most code can be rewritten to be faster. But almost always, ... Pin
Niklas Lindquist20-Apr-11 22:01
memberNiklas Lindquist20-Apr-11 22:01 
GeneralRe: Not sure whether changin the alpha value is a good solution.... Pin
Mukit, Ataul19-Apr-11 21:19
memberMukit, Ataul19-Apr-11 21:19 
GeneralRe: yes, it's a division by 256. try: int av = uAlphaValue + 1;... Pin
ollienator19-Apr-11 20:50
memberollienator19-Apr-11 20:50 
GeneralRe: I think >> 8 means division by 256 and not 255. Can anybody ... Pin
Mukit, Ataul19-Apr-11 19:40
memberMukit, Ataul19-Apr-11 19:40 
GeneralRe: You can unroll the nested loops and just treat them as a con... Pin
basementman14-Apr-11 6:05
memberbasementman14-Apr-11 6:05 
GeneralRe: as mentioned in your point 4 - "Reordering when necessary mi... Pin
Mukit, Ataul12-Apr-11 1:49
memberMukit, Ataul12-Apr-11 1:49 
GeneralRe: You're welcome! Pin
Manfred R. Bihy13-Apr-11 11:17
mvpManfred R. Bihy13-Apr-11 11:17 
GeneralI would not worry about people claiming there will be cache ... Pin
Niklas Lindquist20-Apr-11 2:34
memberNiklas Lindquist20-Apr-11 2:34 
GeneralRe: Thanx.. that was really inpiring Pin
Mukit, Ataul20-Apr-11 19:52
memberMukit, Ataul20-Apr-11 19:52 
GeneralRe: Hoi, I have to contradict here a lot. Go use, for instance, ... Pin
gilgamash20-Sep-11 23:06
membergilgamash20-Sep-11 23:06 
GeneralReason for my vote of 5 Fast and simple thanks. Pin
arm2arm119-Apr-11 0:23
memberarm2arm119-Apr-11 0:23 
GeneralRe: my pleasure.. Pin
Mukit, Ataul19-Apr-11 0:25
memberMukit, Ataul19-Apr-11 0:25 
GeneralThis short paper explains it well and thoroughly: http://sy... Pin
gilgamash12-Apr-11 2:36
membergilgamash12-Apr-11 2:36 
GeneralYou can make it still faster: 1) Replace the divisions by ... Pin
gilgamash12-Apr-11 1:29
membergilgamash12-Apr-11 1:29 
GeneralRe: All i can say is "WOW!!" .. Thnx... it mite really help in f... Pin
Mukit, Ataul12-Apr-11 1:43
memberMukit, Ataul12-Apr-11 1:43 
GeneralRe: why not replace /255 with >>8 ? Pin
ollienator19-Apr-11 7:26
memberollienator19-Apr-11 7:26 
GeneralReason for my vote of 5 Nice! Pin
Manfred R. Bihy11-Apr-11 4:39
mvpManfred R. Bihy11-Apr-11 4:39 
GeneralRe: Finally some appreciation.. thanx :) Pin
Mukit, Ataul11-Apr-11 22:44
memberMukit, 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
Web03 | 2.8.150520.1 | Last Updated 19 Apr 2011
Article Copyright 2011 by Mukit, Ataul
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid