半透明AlphaBlend

AlphaBlend

    函数功能:该函数用来显示透明或半透明像素的位图。

函数原型:

BOOL AlphaBlend(  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
  BLENDFUNCTION blendFunction  // alpha-blending function);

参数:

    hdcDest:指向目标设备环境的句柄。
    nXoriginDest:指定目标矩形区域左上角的X轴坐标,按逻辑单位。
    nYOriginDest:指定目标矩形区域左上角的Y轴坐标,按逻辑单位。
    nWidthDest:指定目标矩形区域的宽度,按逻辑单位。
    hHeghtdest:指向目标矩形区域高度的句柄,按逻辑单位。
    hdcSrc:指向源设备环境的句柄。
    nXOriginSrc:指定源矩形区域左上角的X轴坐标,按逻辑单位。
    nYOriginSrc:指定源矩形区域左上角的Y轴坐标,按逻辑单位。
    nWidthSrc:指定源矩形区域的宽度,按逻辑单位。
    nHeightSrc:指定源矩形区域的高度,按逻辑单位。
    blendFunction:指定用于源位图和目标位图使用的alpha混合功能,用于整个源位图的全局alpha值和格式信息。源和目标混合功能当前只限为AC_SRC_OVER。

 

BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数.定义如下:
typedef struct _BLENDFUNCTION {
  BYTE     BlendOp;
  BYTE     BlendFlags;
  BYTE     SourceConstantAlpha;
  BYTE     AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
BlendOp: 这个参数必须也只能为AC_SRC_OVER(0x00),意思就是把源图片覆盖到目标之上.

BlendFlags: 必须为0

SourceConstantAlpha: 简写为SCA,指定源图片的透明度,这个值是会和源图片的Alpha通道值合并计算的.
//设置透明度,0为完全透明,255为完全不透明  
AlphaFormat: 可以填两种,一种是0x00,一种是AC_SRC_ALPHA(0x01).填0的话,AlphaBlend据说就和BitBlt一样了,我没有试验过~填1的话,源DC必须是32位的DC不然的话,AlphaBlend会返回参数错误.

计算公式(当SCA不是0xFF时):

      输出像素(R,G,B,A) = 源像素(R,G,B,A) * SCA / 0xFF + 目标像素(R,G,B,A) * (1.0 - SCA / 0xFF)

当SCA是0xFF时,计算公式

      输出像素(R,G,B,A) = 源像素(R,G,B,A) + 目标像素(R,G,B,A) * (1.0 - 源像素(A) / 0xFF)

混合计算公式

       输出像素(R,G,B) = 源像素(R,G,B) * SCA / 0xFF + 目标像素(R,G,B) * (1.0 - 源像素(A) / 0xFF * SCA / 0xFF)

 

    AlphaBlend返回值:如果函数执行成功,那么返回值为TRUE;如果函数执行失败,那么返回值为FALSE。
  
    Windows NT:若想获取更多错误信息,请调用GetLastError函数。
    备注:如果源矩形区域与目标矩形区域大小不一样,那么将缩放源位图与目标矩形区域匹配。如果使用SetStretchBltMode函数,那么iStretchMode的值是BLACKONWHITE和WHITEONBLACK,在本函数中,iStretchMode的值自动转换成COLORONCOLOR。目标坐标使用为目标设备环境当前指定的转换方式进行转换。源坐标则使用为源设备环境指定的当前转换方式进行转换。如果源设备环境标识为增强型图元文件设备环境,那么会出错(并且该函数返回FALSE)。如果目标和源位图的色彩格式不同,那么AlphaBlend将源位图转换以匹配目标位图。
    AlphaBlend不支持镜像。如果源或目标区域的宽度或高度为负数,那么调用将失败。

下面是一个例子:
  

#include <windows.h>
#include <atldbcli.h>
#pragma   comment(lib,"Msimg32.lib")
HINSTANCE g_hIns;
HWND g_hWnd;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

TCHAR szText[] = TEXT("win32 AlphaBlend");

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iCmdShow)
{
    g_hIns=hInstance;
    static TCHAR szAppName[]=TEXT("HelloWin");
    HWND hWnd;
    MSG msg;
    WNDCLASS wndClass;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;
    wndClass.lpfnWndProc=WndProc;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hInstance=hInstance;
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.lpszMenuName=NULL;
    wndClass.lpszClassName=szAppName;
    if(!RegisterClass(&wndClass))
    {
        MessageBox(NULL,TEXT("error"),szAppName,MB_ICONERROR|MB_OK);
        return 0;
    }
    hWnd=CreateWindow(szAppName,TEXT("The hello program"),WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);

    //也可以放在此
    ShowWindow(hWnd,iCmdShow);
    UpdateWindow(hWnd);
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    static HDC hdc;
    static HDC hBitmapDC;
    static HBITMAP hBitmap;
    static int w=200;
    static int h=100;
    static BLENDFUNCTION bf = {0};
    PAINTSTRUCT ps;
    switch (message)
    {
    case   WM_PAINT :
    {
        hdc=BeginPaint(hWnd,&ps);
        hBitmapDC = CreateCompatibleDC(hdc);
        hBitmap = CreateCompatibleBitmap(hdc,w,h);
        SelectObject(hBitmapDC,hBitmap);
        SetTextColor(hBitmapDC,RGB(255,0,0));
        TextOut(hBitmapDC,20,20,szText,strlenT(szText));
        
        bf.BlendOp = AC_SRC_OVER;
        bf.BlendFlags = 0;  
        bf.AlphaFormat = 0;
        bf.SourceConstantAlpha = 75;
        AlphaBlend(hdc,0,0,w,h,hBitmapDC,0,0,w,h,bf);

        DeleteObject(hBitmap);
        DeleteDC( hBitmapDC );
        EndPaint (hWnd, &ps) ;
    }
    break;
    case WM_DESTROY :
        PostQuitMessage(0);
        break ;
    }
    return DefWindowProc (hWnd, message, wParam, lParam) ;
}

 

posted @ 2014-04-06 15:33  执迷不悟~  阅读(17540)  评论(1编辑  收藏  举报