GDI/GDI+(2): AlphaBled以及DoAlphaBlend

这2个函数的应用场合不同。



AlphaBlend

用法:

void CWndJustForTest::OnPaint()
{
    CPaintDC dc(this);

    CRect rcDest;
    GetClientRect(rcDest);

    dc.FillSolidRect(&rcDest, RGB(255,255,255));
    
    BITMAP bmpinfo;
    if (::GetObject((HBITMAP)m_hBitmap, sizeof(bmpinfo), &bmpinfo))
    {
        //return CSize((int)bmpinfo.bmWidth, (int)bmpinfo.bmHeight);

        int cx = (int)bmpinfo.bmWidth;
        int cy = (int)bmpinfo.bmHeight;

        CBitmap bmp;
        bmp.CreateCompatibleBitmap(&dc, cx, cy);

        CDC* pDC = new CDC();
        pDC->CreateCompatibleDC(&dc);
        pDC->SelectObject(m_png);

        //DoAlphaBlend(dc.GetSafeHdc(), 0,0, cx, cy, pDC->GetSafeHdc(), 0,0, cx, cy, 126);

        BLENDFUNCTION bf;
        bf.AlphaFormat = 0;
        bf.BlendFlags = 0;
        bf.BlendOp = AC_SRC_OVER;
        bf.SourceConstantAlpha = 255;//透明度0~255
        AlphaBlend(dc.GetSafeHdc(), 0,0, cx, cy, pDC->GetSafeHdc(), 0,0, cx, cy, bf);
    }

}




DoAlphaBlend

http://support.microsoft.com/kb/303916/en-us

代码如下:

dest' = ((weighting * source) + ((255-weighting) * dest)) / 256

/*********************************************************************\ 
*                                                                     *
*  Create24BPPDIBSection(HDC, int, int);                              *
*                                                                     *
*  Purpose:                                                           *
*      Creates a 24 bit-per-pixel DIB section with the specified      *
*      width and height.                                              *
*                                                                     *
\*********************************************************************/ 
HBITMAP Create24BPPDIBSection(HDC hDC, int iWidth, int iHeight)
{
    BITMAPINFO bmi;
    HBITMAP hbm;
    LPBYTE pBits;

    // Initialize header to 0s.
    ZeroMemory(&bmi, sizeof(bmi));

    // Fill out the fields you care about.
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = iWidth;
    bmi.bmiHeader.biHeight = iHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    // Create the surface.
    hbm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, &pBits, NULL, 0);
      
    return(hbm);
}

/*********************************************************************\ 
*                                                                     *
*  BitmapsCompatible(LPBITMAP, LPBITMAP)                              *
*                                                                     *
*  Purpose:                                                           *
*      Compares two bitmap structures to see if the surfaces are      *
*      the same width, height, and pixel format.                       *
*                                                                     *
\*********************************************************************/ 
BOOL BitmapsCompatible(LPBITMAP lpbm1, LPBITMAP lpbm2)
{
    if (lpbm1->bmBitsPixel != lpbm2->bmBitsPixel) return FALSE;
    if (lpbm1->bmPlanes    != lpbm2->bmPlanes)    return FALSE;
    if (lpbm1->bmWidth     != lpbm2->bmWidth)     return FALSE;
    if (lpbm1->bmHeight    != lpbm2->bmHeight)    return FALSE;

    return TRUE;
}

/*********************************************************************\ 
*                                                                     *
*  BOOL BlendImages(HBITMAP, HBITMAP, HBITMAP, DWORD);                *
*                                                                     *
*  Purpose:                                                           *
*      Blends two source images into a destination image              *
*      using a specified weighting value for the first source         *
*      image.                                                         *
*                                                                     *
*  Notes:                                                             *
*      All HBITMAP parameters must be 24 bit-per-pixel DIB sections.   *
*      All HBITMAP parameters must have the same widths and heights.   *
*      Weighting values must be in the range of 0 .. 255.              *
*                                                                     *
\*********************************************************************/ 
BOOL BlendImages(HBITMAP hbmSrc1, HBITMAP hbmSrc2, HBITMAP hbmDst, DWORD dwWeight1)
{
    BITMAP bmSrc1, bmSrc2, bmDst;
    RGBTRIPLE *lprgbSrc1, *lprgbSrc2, *lprgbDst;
    DWORD dwWidthBytes, dwWeight2;
    int x, y;
    
    // Only values between 0 and 255 are valid.
    if (dwWeight1 > 255) return FALSE;
    
    // Get weighting value for second source image.
    dwWeight2 = 255-dwWeight1;
    
    // Get information about the surfaces you were passed.
    if (!GetObject(hbmSrc1, sizeof(BITMAP), &bmSrc1)) return FALSE;
    if (!GetObject(hbmSrc2, sizeof(BITMAP), &bmSrc2)) return FALSE;
    if (!GetObject(hbmDst,  sizeof(BITMAP), &bmDst))  return FALSE;

    // Make sure you have data that meets your requirements.
    if (!BitmapsCompatible(&bmSrc1, &bmSrc2)) return FALSE;
    if (!BitmapsCompatible(&bmSrc1, &bmDst))  return FALSE;
    if (bmSrc1.bmBitsPixel != 24) return FALSE;
    if (bmSrc1.bmPlanes != 1) return FALSE;
    if (!bmSrc1.bmBits || !bmSrc2.bmBits || !bmDst.bmBits) return FALSE;

    dwWidthBytes = bmDst.bmWidthBytes;
    
    // Initialize the surface pointers.
    lprgbSrc1 = bmSrc1.bmBits; 
    lprgbSrc2 = bmSrc2.bmBits;  
    lprgbDst  = bmDst.bmBits;

    for (y=0; y<bmDst.bmHeight; y++) {
        for (x=0; x<bmDst.bmWidth; x++) {
            lprgbDst[x].rgbtRed   = (BYTE)((((DWORD)lprgbSrc1[x].rgbtRed * dwWeight1) + 
                                            ((DWORD)lprgbSrc2[x].rgbtRed * dwWeight2)) >> 8);
            lprgbDst[x].rgbtGreen = (BYTE)((((DWORD)lprgbSrc1[x].rgbtGreen * dwWeight1) + 
                                            ((DWORD)lprgbSrc2[x].rgbtGreen * dwWeight2)) >> 8);
            lprgbDst[x].rgbtBlue  = (BYTE)((((DWORD)lprgbSrc1[x].rgbtBlue * dwWeight1) + 
                                            ((DWORD)lprgbSrc2[x].rgbtBlue * dwWeight2)) >> 8);
        }

        // Move to next scan line.
        lprgbSrc1 = (RGBTRIPLE *)((LPBYTE)lprgbSrc1 + dwWidthBytes);
        lprgbSrc2 = (RGBTRIPLE *)((LPBYTE)lprgbSrc2 + dwWidthBytes);
        lprgbDst  = (RGBTRIPLE *)((LPBYTE)lprgbDst  + dwWidthBytes);
    }

    return TRUE;
}

/*********************************************************************\ 
*                                                                     *
*  BOOL DoAlphaBlend()                                                *
*                                                                     *
*  Purpose:                                                           *
*      Captures a copy of the source and destination areas and        *
*      alpha blends them into a memory surface that it displays       *
*      into the destination area.                                     *     *                                                                     *    
*  Notes:                                                             *
*      Takes the same parameters as the AlphaBlend function except    *
*      that the last parameter is a source weighting value rather     *
*      than a BLENDFUNCTION structure.                                *
*                                                                     *
\*********************************************************************/ 
BOOL DoAlphaBlend(
  HDC hdcDest,                 // Handle to destination DC.
  int nXOriginDest,            // X-coord of upper-left corner.
  int nYOriginDest,            // Y-coord of upper-left corner.
  int nWidthDest,              // Destination width.
  int nHeightDest,             // Destination height.
  HDC hdcSrc,                  // Handle to source DC.
  int nXOriginSrc,             // X-coord of upper-left corner.
  int nYOriginSrc,             // Y-coord of upper-left corner.
  int nWidthSrc,               // Source width.
  int nHeightSrc,              // Source height.
  DWORD dwSourceWeight)        // Source weighting (between 0 and 255).
{
    HDC      hdcSrc1 = NULL;
    HDC      hdcSrc2 = NULL;
    HDC      hdcDst  = NULL;
    HBITMAP  hbmSrc1 = NULL;
    HBITMAP  hbmSrc2 = NULL;
    HBITMAP  hbmDst  = NULL;
    BOOL     bReturn;

    // Create surfaces for sources and destination images.
    hbmSrc1 = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmSrc1) goto HANDLEERROR;

    hbmSrc2 = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmSrc2) goto HANDLEERROR;

    hbmDst  = Create24BPPDIBSection(hdcDest, nWidthDest,nHeightDest);
    if (!hbmDst) goto HANDLEERROR;

    
    // Create HDCs to hold our surfaces.
    hdcSrc1 = CreateCompatibleDC(hdcDest);
    if (!hdcSrc1) goto HANDLEERROR;
    
    hdcSrc2 = CreateCompatibleDC(hdcDest);
    if (!hdcSrc2) goto HANDLEERROR;
    
    hdcDst  = CreateCompatibleDC(hdcDest);
    if (!hdcDst) goto HANDLEERROR;

    
    // Prepare the surfaces for drawing.
    SelectObject(hdcSrc1, hbmSrc1);
    SelectObject(hdcSrc2, hbmSrc2);
    SelectObject(hdcDst,  hbmDst);
    SetStretchBltMode(hdcSrc1, COLORONCOLOR);
    SetStretchBltMode(hdcSrc2, COLORONCOLOR);

    
    // Capture a copy of the source area.
    if (!StretchBlt(hdcSrc1, 0,0,nWidthDest,nHeightDest,
                    hdcSrc,  nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 
                    SRCCOPY))
         goto HANDLEERROR;
    
    // Capture a copy of the destination area.
    if (!StretchBlt(hdcSrc2, 0,0,nWidthDest,nHeightDest,
                    hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
                    SRCCOPY))
         goto HANDLEERROR;

                  
    // Blend the two source areas to create the destination image.
    bReturn = BlendImages(hbmSrc1, hbmSrc2, hbmDst, dwSourceWeight);

    
    // Clean up objects you do not need any longer.
    // You cannot delete an object that's selected into an
    // HDC so delete the HDC first. 
    DeleteDC(hdcSrc1);
    DeleteDC(hdcSrc2);
    DeleteObject(hbmSrc1);
    DeleteObject(hbmSrc2);

    
    // Display the blended (destination) image to the target HDC.
    if (bReturn) {
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
               hdcDst, 0,0, SRCCOPY);
    }

    
    // Clean up the rest of the objects you created.
    DeleteDC(hdcDst);
    DeleteObject(hbmDst);

    return bReturn;

HANDLEERROR:

    if (hdcSrc1) DeleteDC(hdcSrc1);
    if (hdcSrc2) DeleteDC(hdcSrc2);
    if (hdcDst)  DeleteDC(hdcDst);
    if (hbmSrc1) DeleteObject(hbmSrc1);
    if (hbmSrc2) DeleteObject(hbmSrc2);
    if (hbmDst)  DeleteObject(hbmDst);

    return FALSE;
}
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值