您的位置:首页 > 其它

[转] 透明位图的显示

2009-06-17 00:06 381 查看
【原帖地址】
作者:王骏
下载本文示例代码

包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有透明区域位图的方法。

一、TransparentBlt 函数的使用

TransparentBlt 函数在Windows98/Windows2000以上版本运行,系统中需要包含 Msimg32.dll,使用时可以链接 Msimg32.lib。

Windows98下的TransparentBlt会产生资源泄漏,所以不建议在WIN98下使用该函数。

TransparentBlt函数原型如下:
BOOL TransparentBlt(
HDC hdcDest,      // 目标DC
int nXOriginDest,   // 目标X偏移
int nYOriginDest,   // 目标Y偏移
int nWidthDest,     // 目标宽度
int hHeightDest,    // 目标高度
HDC hdcSrc,         // 源DC
int nXOriginSrc,    // 源X起点
int nYOriginSrc,    // 源Y起点
int nWidthSrc,      // 源宽度
int nHeightSrc,     // 源高度
UINT crTransparent  // 透明色,COLORREF类型
);

使用示例:
CBitmap FootballBMP;
FootballBMP.LoadBitmap(IDB_FOOTBALLBMP);
CDC ImageDC;
ImageDC.CreateCompatibleDC(pDC);
CBitmap *pOldImageBMP = ImageDC.SelectObject(&FootballBMP);
TransparentBlt(pDC->m_hDC, 0, 0, 218, 199, ImageDC.m_hDC, 0, 0, 218, 199, RGB(0,0,0xff));
ImageDC.SelectObject(pOldImageBMP);

二、实现TransparentBlt函数

为了理解具有透明色位图的绘制过程,我们来亲手建立一个具有同TransparentBlt功能一致的实验函数,称之为TransparentBlt2。

实验素材:有两张位图:bk.bmp是背景位图,football.bmp包含透明区域,透明色为蓝色RGB(0,0,0xff)

实验目的:以bk.bmp为背景,将football.bmp绘制到背景中,形成如下的最终效果图。

Code

bool TransparentBltU(

HDC dcDest,         // handle to Dest DC

int nXOriginDest,   // x-coord of destination upper-left corner

int nYOriginDest,   // y-coord of destination upper-left corner

int nWidthDest,     // width of destination rectangle

int nHeightDest,    // height of destination rectangle

HDC dcSrc,          // handle to source DC

int nXOriginSrc,    // x-coord of source upper-left corner

int nYOriginSrc,    // y-coord of source upper-left corner

int nWidthSrc,      // width of source rectangle

int nHeightSrc,     // height of source rectangle

UINT crTransparent  // color to make transparent

)

{

if (nWidthDest < 1) return false;

if (nWidthSrc < 1) return false;

if (nHeightDest < 1) return false;

if (nHeightSrc < 1) return false;

HDC dc = CreateCompatibleDC(NULL);

HBITMAP bitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1, GetDeviceCaps(dc,

BITSPIXEL), NULL);

if (bitmap == NULL)

{

DeleteDC(dc);

return false;

}

HBITMAP oldBitmap = (HBITMAP)SelectObject(dc, bitmap);

if (!BitBlt(dc, 0, 0, nWidthSrc, nHeightSrc, dcSrc, nXOriginSrc,

nYOriginSrc, SRCCOPY))

{

SelectObject(dc, oldBitmap);

DeleteObject(bitmap);

DeleteDC(dc);

return false;

}

HDC maskDC = CreateCompatibleDC(NULL);

HBITMAP maskBitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1, 1, NULL);

if (maskBitmap == NULL)

{

SelectObject(dc, oldBitmap);

DeleteObject(bitmap);

DeleteDC(dc);

DeleteDC(maskDC);

return false;

}

HBITMAP oldMask =  (HBITMAP)SelectObject(maskDC, maskBitmap);

SetBkColor(maskDC, RGB(0,0,0));

SetTextColor(maskDC, RGB(255,255,255));

if (!BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,NULL,0,0,BLACKNESS))

{

SelectObject(maskDC, oldMask);

DeleteObject(maskBitmap);

DeleteDC(maskDC);

SelectObject(dc, oldBitmap);

DeleteObject(bitmap);

DeleteDC(dc);

return false;

}

SetBkColor(dc, crTransparent);

BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,dc,0,0,SRCINVERT);

SetBkColor(dc, RGB(0,0,0));

SetTextColor(dc, RGB(255,255,255));

BitBlt(dc, 0,0,nWidthSrc,nHeightSrc,maskDC,0,0,SRCAND);

HDC newMaskDC = CreateCompatibleDC(NULL);

HBITMAP newMask;

newMask = CreateBitmap(nWidthDest, nHeightDest, 1,

GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);

if (newMask == NULL)

{

SelectObject(dc, oldBitmap);

DeleteDC(dc);

SelectObject(maskDC, oldMask);

DeleteDC(maskDC);

DeleteDC(newMaskDC);

DeleteObject(bitmap);

DeleteObject(maskBitmap);

return false;

}

SetStretchBltMode(newMaskDC, COLORONCOLOR);

HBITMAP oldNewMask = (HBITMAP) SelectObject(newMaskDC, newMask);

StretchBlt(newMaskDC, 0, 0, nWidthDest, nHeightDest, maskDC, 0, 0,

nWidthSrc, nHeightSrc, SRCCOPY);

SelectObject(maskDC, oldMask);

DeleteDC(maskDC);

DeleteObject(maskBitmap);

HDC newImageDC = CreateCompatibleDC(NULL);

HBITMAP newImage = CreateBitmap(nWidthDest, nHeightDest, 1,

GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);

if (newImage == NULL)

{

SelectObject(dc, oldBitmap);

DeleteDC(dc);

DeleteDC(newMaskDC);

DeleteObject(bitmap);

return false;

}

HBITMAP oldNewImage = (HBITMAP)SelectObject(newImageDC, newImage);

StretchBlt(newImageDC, 0, 0, nWidthDest, nHeightDest, dc, 0, 0, nWidthSrc,

nHeightSrc, SRCCOPY);

SelectObject(dc, oldBitmap);

DeleteDC(dc);

DeleteObject(bitmap);

BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,

newMaskDC, 0, 0, SRCAND);

BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,

newImageDC, 0, 0, SRCPAINT);

SelectObject(newImageDC, oldNewImage);

DeleteDC(newImageDC);

SelectObject(newMaskDC, oldNewMask);

DeleteDC(newMaskDC);

DeleteObject(newImage);

DeleteObject(newMask);

return true;

}
说明:本文提供的TransparentBlt2函数旨在说明透明位图的显示原理,在Windows2000以上环境实际运用中建议使用现成的TransparentBlt函数来绘制透明位图。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: