如何创建透明内存位图? (在线等待,解决马上给分。)

ColderRain 2002-10-10 08:30:07
CClientDC dc(this);
CDC memDC;
CBitmap bmp;

CRect rcDlg;
GetClientRect(&rcDlg);
memDC.CreateCompatibleDC(&dc);
bmp.CreateCompatibleBitmap(&dc,rcDlg.Width(),rcDlg.Height());
CBitmap * pOldBitmap=memDC.SelectObject(&bmp);
memDC.MoveTo(CPoint(100,100));
memDC.LineTo(CPoint(0,50));

dc.BitBlt(0,0,rcDlg.Width(),rcDlg.Height(),&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBitmap);


如上面的代码,当将bmp复制到窗体上时,bmp的背景色是黑的,如果我要实现透明(就像透明窗体一样)的改怎么办?也就是说当BMP覆盖掉窗体上原来的线条时,不破坏原来的线条。而在BMP上画的线条可以在窗体上存在。
...全文
264 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lshadow 2002-10-10
  • 打赏
  • 举报
回复
帮你up ,给点分吧
ColderRain 2002-10-10
  • 打赏
  • 举报
回复
我用那两个函数,怎么一点反应也没有,还是老样子.
ColderRain 2002-10-10
  • 打赏
  • 举报
回复
先让我试试。
sans 2002-10-10
  • 打赏
  • 举报
回复
思路:
先将目的DC的内容拷贝到你的内存DC中,然后在里面进行操作,最后再将内存DC拷贝回原来显示DC的位置即可。

我这里有一段显示透明GIF图片的代码,你自己看看:
//显示图象,其中:iDLeft,iDTop,iDWidth,iDHeight表示目标区域,
// iSLeft,iSTop,iSWidth,iSHeight表示源区域,
// =-1表示用图象的原来尺寸.
BOOL CGif89a::Show(HDC hDC,int iDLeft,int iDTop,int iDWidth,int iDHeight,
int iSLeft,int iSTop,int iSWidth,int iSHeight)
{
if( m_hBitmap == NULL ) return FALSE;

HDC hMemDC,hMemDC1;
HBITMAP hOldBitmap,hOldBitmap1;//,hBitmap;
int iWidthD,iHeightD;
int iWidthS,iHeightS;

m_hDC = hDC;
iWidthD = iDWidth == -1 ? m_iGifWidth : iDWidth;
iHeightD = iDHeight == -1 ? m_iGifHeight : iDHeight;

iWidthS = iSWidth == -1 ? m_iGifWidth : iSWidth;
iHeightS = iSHeight == -1 ? m_iGifHeight : iSHeight;

iWidthS = iWidthS > iWidthD ? iWidthD : iWidthS;
iHeightS = iHeightS > iHeightD ? iHeightD : iHeightS;

hMemDC=CreateCompatibleDC(m_hDC);
hOldBitmap=(HBITMAP)SelectObject(hMemDC,m_hBitmap);

if(m_bTransparent) //透明显示,着重看这里
{
HBITMAP bmAndBack, bmAndObject,hPicBitmap;
HBITMAP bmBackOld, bmObjectOld,hPicBmOld;
HDC hdcBack, hdcObject,hPicDC;
COLORREF cColor;

if( m_hRedrawBitmap != NULL )
{
DeleteObject( m_hRedrawBitmap );
m_hRedrawBitmap = NULL;
}

m_hRedrawBitmap = CreateCompatibleBitmap(m_hDC,iWidthS,iHeightS);

hMemDC1=CreateCompatibleDC(m_hDC);
hOldBitmap1=(HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap);
BitBlt(hMemDC1,0,0,iWidthS,iHeightS,m_hDC,m_iLeftD+iDLeft,m_iTopD+iDTop,SRCCOPY);

hPicDC = CreateCompatibleDC(m_hDC);
hdcBack = CreateCompatibleDC(m_hDC);
hdcObject = CreateCompatibleDC(m_hDC);
bmAndBack = CreateBitmap(iWidthS,iHeightS,1,1,NULL);
bmAndObject = CreateBitmap(iWidthS,iHeightS,1,1,NULL);
hPicBitmap = CreateCompatibleBitmap(m_hDC,m_iGifWidth,m_iGifHeight);
bmBackOld = (HBITMAP)SelectObject(hdcBack,bmAndBack);
bmObjectOld = (HBITMAP)SelectObject(hdcObject,bmAndObject);
hPicBmOld = (HBITMAP)SelectObject(hPicDC,hPicBitmap);

BitBlt(hPicDC,0,0,m_iGifWidth,m_iGifHeight,hMemDC,0,0,SRCCOPY);
cColor=SetBkColor(hPicDC,m_TransparentColor);

BitBlt(hdcObject,0,0,iWidthS,iHeightS,hPicDC,iSLeft,iSTop,SRCCOPY);

SetBkColor(hPicDC,cColor);
BitBlt(hdcBack,0,0,iWidthS,iHeightS,hdcObject,0,0,NOTSRCCOPY);
BitBlt(hMemDC1,0,0,iWidthS,iHeightS,hdcObject,0,0,SRCAND);
BitBlt(hPicDC,iSLeft,iSTop,iWidthS,iHeightS,hdcBack,0,0,SRCAND);
BitBlt(hMemDC1,0,0,iWidthS,iHeightS,hPicDC,iSLeft,iSTop,SRCPAINT);
DeleteObject(SelectObject(hPicDC,hPicBmOld));
DeleteObject(SelectObject(hdcBack,bmBackOld));
DeleteObject(SelectObject(hdcObject,bmObjectOld));
DeleteDC(hPicDC);
DeleteDC(hdcBack);
DeleteDC(hdcObject);

BitBlt(m_hDC,m_iLeftD+iDLeft,m_iTopD+iDTop,iWidthD,iHeightD,hMemDC1,0,0,SRCCOPY);
SelectObject(hMemDC1,hOldBitmap1);
DeleteDC(hMemDC1);

if( m_hRedrawBitmap != NULL )
{
DeleteObject( m_hRedrawBitmap );
m_hRedrawBitmap = NULL;
}
}
else
{
BitBlt(m_hDC,m_iLeftD+iDLeft,m_iTopD+iDTop,iWidthD,iHeightD,hMemDC,iSLeft,iSTop,SRCCOPY);
}
SelectObject(hMemDC,hOldBitmap);
DeleteDC(hMemDC);
return TRUE;
}
guopo 2002-10-10
  • 打赏
  • 举报
回复
这次我想要分了,我现在的分太不吉利!!


谢谢!
guopo 2002-10-10
  • 打赏
  • 举报
回复
CBmpRgn::CBmpRgn()
{

}

CBmpRgn::~CBmpRgn()
{

}


//返回24位位图实际的多边形区域,将透明颜色指定为(red,green,blue),将其删除,以获取实际位图的
//HRGN,GOOD!!
HRGN CBmpRgn::GenerateRegion(HBITMAP hBitmap, BYTE red, BYTE green, BYTE blue)
{
WORD wBmpWidth,wBmpHeight;
HRGN hRgn, hTmpRgn;

//返回指向位图实际象素的首地址指针,并得到位图的宽度和高度,分别保存在wBmpWidth和wBmpHeight中
BYTE *pPixels = Get24BitPixels(hBitmap, &wBmpWidth, &wBmpHeight);
if (!pPixels)
return NULL;

//根据位图的宽度和高度创建一个矩形
hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
if (!hRgn)
{
delete pPixels;
return NULL;
}

DWORD p=0;
for (WORD y=0; y<wBmpHeight; y++)
{
for (WORD x=0; x<wBmpWidth; x++)
{
BYTE jRed = pPixels[p+2];//每个位图象素点为3字节,R,G,B各站一字节(8位)
BYTE jGreen = pPixels[p+1];
BYTE jBlue = pPixels[p+0];

if (jRed==red && jGreen==green && jBlue==blue)
{
//从区域中删除透明的颜色(red,green,blue),
hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);//从hRgn中删除hTmpRgn
DeleteObject(hTmpRgn);
}

//下一个象素
p+=3;
}
}
delete pPixels;
return hRgn;
}

//函数返回一个指向将hBitmap象素拷贝到一段内存的首地址的指针
BYTE* CBmpRgn::Get24BitPixels(HBITMAP hBitmap, WORD *pwWidth, WORD *pwHeight)
{
BITMAP bmpBmp;
LPBITMAPINFO pbmiInfo;
BITMAPINFO bmiInfo;
WORD wBmpWidth, wBmpHeight;

GetObject(hBitmap, sizeof(bmpBmp),&bmpBmp);
pbmiInfo = (LPBITMAPINFO)&bmpBmp;

wBmpWidth = (WORD)pbmiInfo->bmiHeader.biWidth;//得到位图的实际宽度
wBmpWidth -= (wBmpWidth%4);//得到位图在内存中的宽度(必须是4的倍数)
wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;//得到位图的高度

*pwWidth = wBmpWidth;//将内存中位图的宽度和高度返回给调用者
*pwHeight = wBmpHeight;

BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];//分配存储位图实际象素值的内存区,每象素占3字节
if (!pPixels) //内存分配失败、或空位图
return NULL;

HDC hDC =::GetWindowDC(NULL);//得到窗口设备句柄,包括菜单、状态条、工具栏、滚动条,可在上面作图

//填充位图信息头
bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiInfo.bmiHeader.biWidth = wBmpWidth;
bmiInfo.bmiHeader.biHeight = -wBmpHeight;
bmiInfo.bmiHeader.biPlanes = 1;
bmiInfo.bmiHeader.biBitCount = 24;
bmiInfo.bmiHeader.biCompression = BI_RGB;
bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
bmiInfo.bmiHeader.biXPelsPerMeter = 0;
bmiInfo.bmiHeader.biYPelsPerMeter = 0;
bmiInfo.bmiHeader.biClrUsed = 0;
bmiInfo.bmiHeader.biClrImportant = 0;

// 将位图象素拷贝到以pPixels指向的内存存储区
int iRes = GetDIBits(hDC,hBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);

::ReleaseDC(NULL,hDC);

if (!iRes)
{
delete pPixels;
return NULL;
};

return pPixels;
}

guopo 2002-10-10
  • 打赏
  • 举报
回复
class CBmpRgn
{
public:
CBmpRgn();
virtual ~CBmpRgn();

public:
HRGN GenerateRegion(HBITMAP hBitmap, BYTE red, BYTE green, BYTE blue);


protected:
BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight);

};

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧