您的位置:首页 > 其它

VC透明显示带透明度PNG图片及不带透明度的图片

2012-11-06 15:42 591 查看
一、显示带透明度的PNG图片

PNG图片的透明背景总是一片白色,后来才发现这其实是微软GDI+的设计问题,PNG图片是ARGB,使用GDI+载入图片的时候,GDI+会默认已经进行了预剩运算(PARGB),即每象素的实际值是已经和ALPHA值按比例相乘的结果,实际上它根本就没有做预乘,在使用透明图片的象素ALPHA通道的时候,CImage内部正是调用的AlphaBlend,没有预乘的图当作预乘的图片处理的结果就是这相当于一张和纯白背景进行了预剩,所以图象总是出现白色背景。所以先要进行处理一下:

CImage img;

HRESULT result = img.Load(_T("(1.png"));

for(int i = 0; i < img.GetWidth(); i++)

{

for(int j = 0; j < img.GetHeight(); j++)

{

unsigned char* pucColor = reinterpret_cast<unsigned char *>(img.GetPixelAddress(i , j));

pucColor[0] = pucColor[0] * pucColor[3] / 255;

pucColor[1] = pucColor[1] * pucColor[3] / 255;

pucColor[2] = pucColor[2] * pucColor[3] / 255;

}

}

然后再Draw到对应的DC上

img.Draw(pDC->m_hDC,0,0);

二、显示不带透明度的图片,且要透明显示:

void AlphaBmp(HDC hdc,HBITMAP hBitmap,int x,int y,short limit,HRGN hRgn,COLORREF col)

{

BLENDFUNCTION blendfunc;

HDC hMaskDc;

HBITMAP hOld=NULL;

BITMAP Bmp;

blendfunc.BlendFlags=0;

blendfunc.AlphaFormat=0;

blendfunc.SourceConstantAlpha=(unsigned char)limit;

blendfunc.BlendOp=AC_SRC_OVER;

GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&Bmp);

hMaskDc=CreateCompatibleDC(hdc);

hOld=(HBITMAP)SelectObject(hMaskDc,hBitmap);

HDC hTempDC=CreateCompatibleDC(hdc);

HBITMAP hBitmap2=CreateCompatibleBitmap(hdc,Bmp.bmWidth,Bmp.bmHeight);

hOld=(HBITMAP)SelectObject(hTempDC,hBitmap2);

BitBlt(hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,hdc,0,0,SRCCOPY);

AlphaBlend (hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,hMaskDc,0,0,Bmp.bmWidth,Bmp.bmHeight,blendfunc);

HRGN hR=CreateRectRgn(0,0,Bmp.bmWidth,Bmp.bmHeight);

HBRUSH hbr=CreateSolidBrush(col);

CombineRgn(hR,hR,hRgn,RGN_DIFF);

FillRgn(hTempDC,hR,hbr);

TransparentBlt(hdc,x,y,Bmp.bmWidth,Bmp.bmHeight,hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,col);

SelectObject(hTempDC,hOld);

DeleteObject(hBitmap2);

DeleteObject(hR);

DeleteObject(hbr);

DeleteDC(hTempDC);

SelectObject(hMaskDc,hOld);

DeleteDC(hMaskDc);

}

参数的含义一次是:hdc为要显示图片的DC

hBitmap为要显示的图片句柄

x,y为坐标

limit为透明度(0-255)

hRgn为图片除掉要屏蔽的颜色的区域(对于球体就是一个圆形区域)

col为要屏蔽的颜色(例如一幅周围是白色的球,不显示周围的白色,只要球(白色就是屏蔽色))

对于hRgn有一点,怎么得到这个区域呢,看下面这个函数:

HRGN BitmapToRgn(HBITMAP hBitmap,COLORREF col)

{

HDC hMemDc;

HBITMAP hOld;

COLORREF CPixel;

HRGN rTemp,hGoal;

BITMAP Bmp;

GetObject(hBitmap,sizeof(BITMAP),&Bmp);

hMemDc=CreateCompatibleDC(NULL);

hOld=(HBITMAP)SelectObject(hMemDc,hBitmap);

hGoal=CreateRectRgn(0,0,Bmp.bmWidth,Bmp.bmHeight);

for(int x=0;x<=Bmp.bmWidth;x++)

for(int y=0;y<=Bmp.bmHeight;y++)

{

CPixel=GetPixel(hMemDc,x,y);

if(CPixel==col)

{

rTemp=CreateRectRgn(x,y,x+1,y+1);

CombineRgn(hGoal,hGoal,rTemp,RGN_XOR);

DeleteObject(rTemp);

}

}

SelectObject(hMemDc,hOld);

DeleteDC(hMemDc);

return hGoal;

}

参数一次是hBitmap为要得到区域的位图,col为屏蔽色

用法例子为:

HBITMAP hBitmap=LoadBitmap(GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP2));

HRGN hrgn=BitmapToRgn(hBitmap,RGB(255,0,255));

AlphaBmp(hDc,hBitmap,450,0,200,hrgn,RGB(255,0,255));

DeleteObject(hBitmap);

DeleteObject(hrgn);//为了提高速度,这个应该用全局变量保存,不易频繁删除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: