一张在内存 cdc 中画好的位图有没有 HBITMAP?如何获取?

happyhhb 2007-05-06 01:10:06
我用下面的方法在cdc上画了一张图:

CDC MemDC; //首先定义一个显示设备对象
CBitmap MemBitmap; //定义一个位图对象
MemDC.CreateCompatibleDC(NULL); //随后建立与屏幕显示兼容的内存显示设备
MemBitmap.CreateCompatibleBitmap(pDC,100,100);//下面建立一个与屏幕显示兼容的位图

MemDC.SelectObject(&MemBitmap); //将位图选入到内存显示设备中
MemDC.MoveTo(0,0); //绘图
MemDC.LineTo(100,100);

这样在内存中画好的位图,有HBITMAP吗,如何获得它的 HBITMAP?
除了loadimage()外,还有什么方法可以获得位图的 HBITMAP?

...全文
1340 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
rainv 2007-05-07
  • 打赏
  • 举报
回复
mark
xteamx 2007-05-07
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/5513/5513571.xml?temp=.6879541
大家帮帮我,看一下我的贴子
yxz_lp 2007-05-06
  • 打赏
  • 举报
回复
这是我在单文档界面OnDraw里的代码,能成功复制DC里的位图,供你参考。
void CbmpView::OnDraw(CDC* pDC)
{
CbmpDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: 在此处为本机数据添加绘制代码
CDC meDC;
meDC.CreateCompatibleDC(pDC);
CImage img;
img.Load(TEXT("Water lilies.jpg"));
CBitmap bmp;
bmp.Attach(img.Detach());
meDC.SelectObject(&bmp);
meDC.MoveTo(0,0);
meDC.LineTo(1000,1000);
BITMAP bmpif;
memset(&bmpif,0,sizeof(bmpif));

bmp.GetBitmap(&bmpif);
CRect rect;
GetClientRect(&rect);
CPoint poin[3]={CPoint(0,0),CPoint(0,bmpif.bmWidth),CPoint(0,bmpif.bmHeight)};
CBitmap cbmp;
//cbmp.CreateBitmap(bmpif.bmWidth,bmpif.bmHeight,1,1,NULL);
if(!pDC->PlgBlt(poin,&meDC,0,0,bmpif.bmWidth,bmpif.bmHeight,cbmp,0,0))
AfxMessageBox(TEXT("没有成功"));
meDC.SelectObject(&cbmp);
//meDC .DrawState(CPoint(0,0),rect.Size(),cbmp,DST_BITMAP|DSS_NORMAL);
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&meDC,0,0,SRCCOPY);

}
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
另外建立了一个对话框程序,试验如上代码

我先在显示区域显示了一张位图,然后用上面的代码载入第二张位图并在其上 LineTo 了一条线
当执行到 memDC.DrawState();Invalidate(); 时我满以为会显示第二张位图,即使没有那条线

但我惊讶的发现,执行的结果居然是什么都没变,仍然显示着第一张图
第二张位图为什么没有显示出来?

why ? 请告诉我好吗?
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
又试了一下,如果把最后一句 Invalidate(); 屏蔽掉,屏幕就不黑了,但显示的仍然不是被绘制过的图,是原图,为什么呢?
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
综合了yxz_lp() ,livedeal(怀念) 的方法,写了如下代码:

 CDC vMemDC; //首先定义一个显示设备对象
 HBITMAP tempBmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
"c:\\dx.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(tempBmp)
{
vMemDC.CreateCompatibleDC(NULL);
SelectObject(vMemDC,tempBmp);
vMemDC.MoveTo(0,0); //绘图
vMemDC.LineTo(1000,1000);

CPoint poin[3]={CPoint(0,0),CPoint(0,image_size.cx),CPoint(0,image_size.cy)};
CBitmap cbmp;
cbmp.CreateBitmap(image_size.cx,image_size.cy,1,1,NULL);
memDC.PlgBlt(poin,&vMemDC,0,0,image_size.cx,image_size.cx,cbmp,0,0); //copy bmp

HBITMAP hBmp = (HBITMAP)(cbmp); //获取cbmp的 HBITMAP
MessageBox("here"); //在此设置了一个断点,过了这个对话框,客户区就变黑了
CPoint point(-x_offset,-y_offset);
memDC.DrawState(point,image_size,hBmp,DST_BITMAP|DSS_NORMAL);
Invalidate();
}

结果是显示窗都黑了,我是哪里写错了吗?
yxz_lp 2007-05-06
  • 打赏
  • 举报
回复
CRect rect;
GetClientRect(&rect);
CPoint poin[3]={CPoint(0,0),CPoint(0,rect.right),CPoint(0,rect.bottom)};
CBitmap cbmp;
cbmp.CreateBitmap(rect.Width(),rect.Height(),1,1,NULL);
pDC->PlgBlt(poin,&meDC,0,0,rect.Width(),rect.Height(),cbmp,0,0)
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
请问 liangyan1120_0() :
  用CreateDIBSection创建的位图,可以导入一个现存的位图吗?
  我上网搜了一下,都是建立空白位图的,不知道有没有方法可以实现将位图写入其中?

谢谢^_^

回 yxz_lp() :
  PlgBlt()在网上的资料超少耶,头大,谢了
yxz_lp 2007-05-06
  • 打赏
  • 举报
回复
是这个意思呀!那你就用PlgBlt()把dc里的内容拷贝到cCccBmp位图里,具体怎么操作你自己再研究研究。

happyhhb 2007-05-06
  • 打赏
  • 举报
回复
再用上 b2b160() 的方法,在上面的代码中间*号的位置添加了如下代码:

HBITMAP hhBitMap = (HBITMAP)MemDC.GetCurrentBitmap();
HBITMAP cCccBmp = (HBITMAP)::SelectObject(MemDC.m_hDC, hhBitMap);

但显示的也还不是被绘制后的位图,天啊,崩溃ing

请指教,谢谢
liangyan1120_0 2007-05-06
  • 打赏
  • 举报
回复
兼容位图和 普通的位图是不一样的,在你画图之前最好先用CreateDIBSection创建一个位图,然后在新创建的位图中作图,最后调用DrawState
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
报告 yxz_lp() ,我用了你的方法,在上面的代码中间添加了如下一句代码:
  
  HBITMAP cCccBmp = (HBITMAP)MemDC.GetCurrentBitmap();

但结果显示的并不是被绘制后的位图,为什么呢?

谢谢
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
我再问直接点哈:
CDC MemDC; //首先定义一个显示设备对象
HBITMAP tempBmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), "c;\\dx.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
if(tempBmp)
{
MemDC.CreateCompatibleDC(NULL);
SelectObject(MemDC,tempBmp);
MemDC.MoveTo(0,0); //绘图
MemDC.LineTo(1000,1000);

******中间这里加上什么代码可以得到cCccBmp 让DrawState正确显示 ?**************
|
CPoint point(-800,-800);
memDC.DrawState(point,image_size,cCccBmp,DST_BITMAP|DSS_NORMAL);
Invalidate();
}

 麻烦大家了,这个问题困扰我很久了,谢谢回答,我把分提到100吧,谢谢
b2b160 2007-05-06
  • 打赏
  • 举报
回复
用SelectObject,就能返回你原来HDC里面的位图.
livedeal 2007-05-06
  • 打赏
  • 举报
回复
HBITMAP hBmp = (HBITMAP)(MemBitmap);//(HBITMAP)是CBitmap类重载了的操作符.
yxz_lp 2007-05-06
  • 打赏
  • 举报
回复
pDC->GetCurrentBitmap();
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
还有一个方法:
 CDC MemDC; //首先定义一个显示设备对象
 HBITMAP tempBmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(),
     "c:\\dx.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
 if(tempBmp)
 {
   MemDC.CreateCompatibleDC(NULL);
   SelectObject(MemDC,tempBmp);
   MemDC.MoveTo(0,0); //绘图
   MemDC.LineTo(100,100);
   pDC->BitBlt(0,0,200,200,&MemDC,0,0,SRCCOPY); //将内存中的图拷贝到屏幕上
 }

程序运行的结果是绘制好的图片已经显示出来了,但因为涉及滚动条操作,最后一步的显示方式我想用 pDC.DrawState(point,image_size,tempBmp,DST_BITMAP|DSS_NORMAL);的方式显示出来,可结果是显示原来没有修改过的位图(原因当然是用了tempBmp,它指向了原来的位图)
so ,如何拿到内存中画好的位图的 HBITMAP呢, 我该怎么做呢?

谢谢回答^_^
happyhhb 2007-05-06
  • 打赏
  • 举报
回复
我靠, livedeal(怀念) 好强悍, 终于搞定了
同时也谢谢 liangyan1120_0() 和 yxz_lp() 给我上了精彩一课, 呵呵

结贴了
livedeal 2007-05-06
  • 打赏
  • 举报
回复
MemDC.CreateCompatibleDC(NULL);
HGDIOBJ TmpObj=MemDC.SelectObject(tempBmp);
MemDC.MoveTo(0,0); //绘图
MemDC.LineTo(100,100);
MemDC.SelectObject(TmpObj);
MemDC.DeleteDC();

tempBmp要释放出来才可以用
liangyan1120_0 2007-05-06
  • 打赏
  • 举报
回复
粘一个我写的吧,你试试:
CClientDC dc(this);

//设置位图信息
BITMAPINFOHEADER BMIH;
memset(&BMIH,0,sizeof(BITMAPINFOHEADER));
BYTE * pDrawingSurfaceBits=NULL;
BMIH.biSize=sizeof(BITMAPINFOHEADER);
BMIH.biBitCount=24;
BMIH.biPlanes=1;
BMIH.biCompression=BI_RGB;
BMIH.biWidth=m_num+80;
BMIH.biHeight=541;
BMIH.biSizeImage=((((BMIH.biWidth*BMIH.biBitCount)+31) & ~31) >>3)*BMIH.biHeight;
HBITMAP hbitmap=CreateDIBSection(dc.GetSafeHdc(),(CONST BITMAPINFO *)&BMIH,DIB_RGB_COLORS, (void **)&pDrawingSurfaceBits,
NULL,0);
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(&dc);
HBITMAP hOldBitmap=(HBITMAP)SelectObject(dcCompatible.GetSafeHdc(),hbitmap);
dcCompatible.FillSolidRect(0,0,m_num+80,541,RGB(255,255,255));
下面就可以在兼容DC里面画图了;
画完之后再SelectObject(dcCompatible.GetSafeHdc(),hOldBitmap);
之后hbitmap就可用了,你试试

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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