注:前景图的背景可为绿,红,黑。在VC++用API 画透明图
不要VB环境 API和VC++ MFC.消息循环代码,
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
break;
case WM_KEYUP:
{ HDC hdc=GetDC(hwnd);
HDC pDC=CreateCompatibleDC(hdc);
HBITMAP hbit=(HBITMAP)LoadImage(NULL,"c:\\dd.bmp",IMAGE_BITMAP,200,200,LR_LOADFROMFILE); //背景图
HBITMAP actbit=(HBITMAP)LoadImage(NULL,"c:\\00.bmp",IMAGE_BITMAP,64,128,LR_LOADFROMFILE); //前景图
SelectObject(pDC,hbit);
BitBlt(hdc,0,0,200,200,pDC,0,0,SRCCOPY);
SelectObject(pDC,actbit);
BitBlt(hdc,0,0,64,128,pDC,0,0,SRCCOPY);
} break;
case WM_DESTROY: PostQuitMessage(0);
break;
case WM_COMMAND:
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return (0);
}
不要VB环境 API和VC++ MFC.消息循环代码,
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
break;
case WM_KEYUP:
{ HDC hdc=GetDC(hwnd);
HDC pDC=CreateCompatibleDC(hdc);
HBITMAP hbit=(HBITMAP)LoadImage(NULL,"c:\\dd.bmp",IMAGE_BITMAP,200,200,LR_LOADFROMFILE); //背景图
HBITMAP actbit=(HBITMAP)LoadImage(NULL,"c:\\00.bmp",IMAGE_BITMAP,64,128,LR_LOADFROMFILE); //前景图
SelectObject(pDC,hbit);
BitBlt(hdc,0,0,200,200,pDC,0,0,SRCCOPY);
SelectObject(pDC,actbit);
BitBlt(hdc,0,0,64,128,pDC,0,0,SRCCOPY);
} break;
case WM_DESTROY: PostQuitMessage(0);
break;
case WM_COMMAND:
break;
default:
return DefWindowProc(hwnd,message,wParam,lParam);
}
return (0);
}
这里主要用到的是GetBitmapBits和SetBitmapBits这两个都是CBitmap的成员函数,一个取位图数据到一个数组,一个将数组值设为位图内容。
a)直接用GDI, 用GetBitmapBits得到图像信息,然后用AlphaBlend实现透明通道,最后SetBitmapBits得到透明图像。
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
);
注意最后一个函数,
typedef struct _BLENDFUNCTION {
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
查看MSDN,里面有AlphaBlend通道的转换公式b)采用双缓冲,先把图像放入内存再进行上述处理
如果你想更高级的透明模式可以用到图像混合技术,但这基本上都是取出位图的Bits出来进行运算的.我想上面的两种方法应该可以满足你的要求
能设置透明色
另外一种就是自己获得目标和源的像素位,自己计算了,这个如果不是做一些图形处理软件,单单做个界面,是没有必要的。
楼主的意图是实现包含掩模位图的区域透明,TransparentBlt其实并不是最佳选择。因为掩模位图已经得到了,TransparentBlt只能采用一种键控色(即透明色),那么有些不想透明的点如果和这个颜色一样,也会被透明掉,采用掩模,就不会有这种现象。
所以最好的方法是自己调用BitBlt,配合合适的ROP2就可以了(前提是你的掩模颜色必须为单色,就是只含白黑)。呵呵,其实本不必绕圈子的。ROP2涉及的步骤比较多,还有一个一蹴而就的函数(针对你的掩模),就是三元Blt函数:PlgBlt,你可以查一下MSDN,它只是在二元BitBlt的基础上加了一个掩模DC,正好合适你的用途。
{
BITMAP OneBitmap;
BITMAP TwoBitmap; GetObject(hOneBitmap, sizeof(BITMAP), &OneBitmap);
GetObject(hTwoBitmap, sizeof(BITMAP), &TwoBitmap); int nOneImageWidth = OneBitmap.bmWidth;
int nOneImageHeight = OneBitmap.bmHeight; int nTwoImageWidth = TwoBitmap.bmWidth;
int nTwoImageHeight = TwoBitmap.bmHeight; if (nOneImageWidth < nTwoImageWidth)
{
nOneImageWidth = nTwoImageWidth;
}
else
{
nTwoImageWidth = nOneImageWidth;
}
if (nOneImageHeight < nTwoImageHeight)
{
nOneImageHeight = nTwoImageHeight;
}
else
{
nTwoImageHeight = nOneImageHeight;
} int nImageWidth = nOneImageWidth;
int nImageHeight = nOneImageHeight; CDC MemDC1, MemDC2;
HBITMAP hOldBitmap1 = NULL, hOldBitmap2 = NULL;
BYTE *pOneBits = NULL;
MemDC1.CreateCompatibleDC(pDC);
MemDC2.CreateCompatibleDC(pDC);
HBITMAP hOneBmp = NULL;
hOneBmp = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pOneBits);
hOldBitmap1 = (HBITMAP)SelectObject(MemDC1.m_hDC, hOneBmp);
hOldBitmap2 = (HBITMAP)SelectObject(MemDC2.m_hDC, hOneBitmap);
//BitBlt(MemDC1.m_hDC, 0, 0, m_nTwoImage_w, m_nTwoImage_h, MemDC2.m_hDC, 0, 0, SRCCOPY);
StretchBlt(MemDC1.m_hDC, 0, 0, nImageWidth, nImageHeight,
MemDC2.m_hDC, 0, 0, OneBitmap.bmWidth, OneBitmap.bmHeight, SRCCOPY); CDC MemDC3, MemDC4;
HBITMAP hOldBitmap3 = NULL, hOldBitmap4 = NULL;
BYTE *pTwoBits = NULL;
MemDC3.CreateCompatibleDC(pDC);
MemDC4.CreateCompatibleDC(pDC);
HBITMAP hTwoBmp = NULL;
hTwoBmp = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pTwoBits);
hOldBitmap3 = (HBITMAP)SelectObject(MemDC3.m_hDC, hTwoBmp);
hOldBitmap4 = (HBITMAP)SelectObject(MemDC4.m_hDC, hTwoBitmap);
//BitBlt(MemDC3.m_hDC, 0, 0, m_nTwoImage_w, m_nTwoImage_h, MemDC4.m_hDC, 0, 0, SRCCOPY);
StretchBlt(MemDC3.m_hDC, 0, 0, nImageWidth, nImageHeight,
MemDC4.m_hDC, 0, 0, TwoBitmap.bmWidth, TwoBitmap.bmHeight, SRCCOPY); CDC MemDC5;
HBITMAP hOldBitmap5 = NULL;
BYTE* pNewBits=NULL;
MemDC5.CreateCompatibleDC(pDC);
HBITMAP hNewBitmap = NULL;
hNewBitmap = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pNewBits);
hOldBitmap5 = (HBITMAP)SelectObject(MemDC5.m_hDC, hNewBitmap); int linebytes=0;
int col=0; int line=(((nImageWidth*24)+31)>>5)<<2;
linebytes = line;
col = nImageHeight;
for(int j=0;j<col;j++)
{
for(int i=0;i<linebytes;i++)
{
*(pNewBits + j*line + i)=(*(pOneBits + j*line + i)*Alpha +
*(pTwoBits+j*line+i)*(100-Alpha))/100;
}
} BitBlt(pDC->m_hDC, 0, 0, ClientRect.Width(), ClientRect.Height(), MemDC5.m_hDC, 0, 0, SRCCOPY);
//StretchBlt(pDC->m_hDC, 0, 0, m_ClientRect.Width(), m_ClientRect.Height(),
// MemDC5.m_hDC, 0, 0, m_nOneImage_w, m_nOneImage_h, SRCCOPY); SelectObject(MemDC5.m_hDC,hOldBitmap5);
MemDC5.DeleteDC();
SelectObject(MemDC4.m_hDC,hOldBitmap4);
MemDC4.DeleteDC();
SelectObject(MemDC3.m_hDC,hOldBitmap3);
MemDC3.DeleteDC();
SelectObject(MemDC2.m_hDC,hOldBitmap2);
MemDC2.DeleteDC();
SelectObject(MemDC1.m_hDC,hOldBitmap1);
MemDC1.DeleteDC();
}HBITMAP CreateBitmapSection(HDC hdc,int cx,int cy,BYTE** ppbit)
{
BITMAPINFO bmi ;
memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER) ;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biWidth = cx;
bmi.bmiHeader.biHeight = -cy; return CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void**)ppbit,NULL,0);
}注:只需传递当前DC、两张位图的句柄、当前DC的rect、Alpha值(传递50为半透明)到TransParentPicture()即可实现透明。
{
BITMAP OneBitmap;
BITMAP TwoBitmap; GetObject(hOneBitmap, sizeof(BITMAP), &OneBitmap);
GetObject(hTwoBitmap, sizeof(BITMAP), &TwoBitmap); int nOneImageWidth = OneBitmap.bmWidth;
int nOneImageHeight = OneBitmap.bmHeight; int nTwoImageWidth = TwoBitmap.bmWidth;
int nTwoImageHeight = TwoBitmap.bmHeight; if (nOneImageWidth < nTwoImageWidth)
{
nOneImageWidth = nTwoImageWidth;
}
else
{
nTwoImageWidth = nOneImageWidth;
}
if (nOneImageHeight < nTwoImageHeight)
{
nOneImageHeight = nTwoImageHeight;
}
else
{
nTwoImageHeight = nOneImageHeight;
} int nImageWidth = nOneImageWidth;
int nImageHeight = nOneImageHeight; CDC MemDC1, MemDC2;
HBITMAP hOldBitmap1 = NULL, hOldBitmap2 = NULL;
BYTE *pOneBits = NULL;
MemDC1.CreateCompatibleDC(pDC);
MemDC2.CreateCompatibleDC(pDC);
HBITMAP hOneBmp = NULL;
hOneBmp = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pOneBits);
hOldBitmap1 = (HBITMAP)SelectObject(MemDC1.m_hDC, hOneBmp);
hOldBitmap2 = (HBITMAP)SelectObject(MemDC2.m_hDC, hOneBitmap);
//BitBlt(MemDC1.m_hDC, 0, 0, m_nTwoImage_w, m_nTwoImage_h, MemDC2.m_hDC, 0, 0, SRCCOPY);
StretchBlt(MemDC1.m_hDC, 0, 0, nImageWidth, nImageHeight,
MemDC2.m_hDC, 0, 0, OneBitmap.bmWidth, OneBitmap.bmHeight, SRCCOPY); CDC MemDC3, MemDC4;
HBITMAP hOldBitmap3 = NULL, hOldBitmap4 = NULL;
BYTE *pTwoBits = NULL;
MemDC3.CreateCompatibleDC(pDC);
MemDC4.CreateCompatibleDC(pDC);
HBITMAP hTwoBmp = NULL;
hTwoBmp = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pTwoBits);
hOldBitmap3 = (HBITMAP)SelectObject(MemDC3.m_hDC, hTwoBmp);
hOldBitmap4 = (HBITMAP)SelectObject(MemDC4.m_hDC, hTwoBitmap);
//BitBlt(MemDC3.m_hDC, 0, 0, m_nTwoImage_w, m_nTwoImage_h, MemDC4.m_hDC, 0, 0, SRCCOPY);
StretchBlt(MemDC3.m_hDC, 0, 0, nImageWidth, nImageHeight,
MemDC4.m_hDC, 0, 0, TwoBitmap.bmWidth, TwoBitmap.bmHeight, SRCCOPY); CDC MemDC5;
HBITMAP hOldBitmap5 = NULL;
BYTE* pNewBits=NULL;
MemDC5.CreateCompatibleDC(pDC);
HBITMAP hNewBitmap = NULL;
hNewBitmap = CreateBitmapSection(pDC->m_hDC, nImageWidth, nImageHeight, &pNewBits);
hOldBitmap5 = (HBITMAP)SelectObject(MemDC5.m_hDC, hNewBitmap); int linebytes=0;
int col=0; int line=(((nImageWidth*24)+31)>>5)<<2;
linebytes = line;
col = nImageHeight;
for(int j=0;j<col;j++)
{
for(int i=0;i<linebytes;i++)
{
*(pNewBits + j*line + i)=(*(pOneBits + j*line + i)*Alpha +
*(pTwoBits+j*line+i)*(100-Alpha))/100;
}
} BitBlt(pDC->m_hDC, 0, 0, ClientRect.Width(), ClientRect.Height(), MemDC5.m_hDC, 0, 0, SRCCOPY);
//StretchBlt(pDC->m_hDC, 0, 0, m_ClientRect.Width(), m_ClientRect.Height(),
// MemDC5.m_hDC, 0, 0, m_nOneImage_w, m_nOneImage_h, SRCCOPY); SelectObject(MemDC5.m_hDC,hOldBitmap5);
MemDC5.DeleteDC();
SelectObject(MemDC4.m_hDC,hOldBitmap4);
MemDC4.DeleteDC();
SelectObject(MemDC3.m_hDC,hOldBitmap3);
MemDC3.DeleteDC();
SelectObject(MemDC2.m_hDC,hOldBitmap2);
MemDC2.DeleteDC();
SelectObject(MemDC1.m_hDC,hOldBitmap1);
MemDC1.DeleteDC();
}HBITMAP CreateBitmapSection(HDC hdc,int cx,int cy,BYTE** ppbit)
{
BITMAPINFO bmi ;
memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER) ;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biWidth = cx;
bmi.bmiHeader.biHeight = -cy; return CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void**)ppbit,NULL,0);
}注:只需传递当前DC、两张位图的句柄、当前DC的rect、Alpha值(传递50为半透明)到TransParentPicture()即可实现透明。