GetDIBits获取不到位图实际数据

shuimx 2011-01-13 08:25:10
想用UDP传送位图。因此想知道位图的那些必要信息是要传送的。我就写了一个测试程序。
(1)自定义了一副位图,通过GetDIBits是可以得到位图的实际数据
void CDeskTopDlg::OnButton3()
{
// TODO: Add your control notification handler code here
CClientDC dc(this);

CBitmap bm;
bm.LoadBitmap(IDB_BITMAP1);
BITMAP bmpInfo;
bm.GetBitmap(&bmpInfo);
char *lpBits = NULL;
int biSizeImage = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; //计算位图数据需要多少字节
lpBits =new char[biSizeImage];
bm.GetBitmapBits(biSizeImage, lpBits);//获取位图的实际数据

BITMAPINFO BitmapInfo;
BitmapInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
BitmapInfo.bmiHeader.biWidth=bmpInfo.bmWidth;
BitmapInfo.bmiHeader.biHeight=bmpInfo.bmHeight;
BitmapInfo.bmiHeader.biPlanes=1;
BitmapInfo.bmiHeader.biBitCount=32;//这里是位图的颜色位数,如果你的位图不是真彩色的,也就是小于等于8位,那就麻烦了,你还要编程实现BitmapInfo.bmiColors结构,所以建议将位图设计成真彩色的,不要吝惜那点空间!
BitmapInfo.bmiHeader.biCompression=BI_RGB;
BitmapInfo.bmiHeader.biClrUsed=0;
BitmapInfo.bmiHeader.biSizeImage=0;
BitmapInfo.bmiHeader.biXPelsPerMeter=0;
BitmapInfo.bmiHeader.biYPelsPerMeter=0;
BitmapInfo.bmiHeader.biClrImportant=0;

CRect rc;
GetDlgItem(IDC_DT)->GetWindowRect(&rc);
ScreenToClient(&rc);
StretchDIBits(dc.m_hDC,rc.left,rc.top+rc.Height(),rc.Width(),-rc.Height(),
0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,lpBits,&BitmapInfo,DIB_RGB_COLORS,SRCCOPY);

delete [] lpBits;
}
(2)但是当我用获取桌面的位图时就不能正确显示位图了,而是全黑色。为了做对比,放置了两个picture控件,一个可以正常显示 StretchBlt,另一个全是黑色GetDIBits。我调试查看信息发现执行GetDIBits语句后,pData指向的内容全是0。。。
CClientDC dc(this);

CDC* pDeskDC = GetDesktopWindow()->GetDC(); //获取桌面画布对象
int width = 1440; //获取屏幕的宽度
int height = 900;

CDC memDC; //定义一个内存画布
memDC.CreateCompatibleDC(&dc);//创建一个兼容的画
CBitmap bmp;
// bmp.LoadBitmap(IDB_BITMAP1);
bmp.CreateCompatibleBitmap(pDeskDC,width,height); //创建兼容位图
memDC.SelectObject(&bmp); //选中位图对象

BITMAP bitmap;
bmp.GetBitmap(&bitmap);
CRect rc;
GetDlgItem(IDC_DT)->GetWindowRect(&rc);
ScreenToClient(&rc);
dc.StretchBlt(rc.left,rc.top,rc.Width(),rc.Height(),pDeskDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);//显示桌面位图正常
//////////////////////////////////////////////////////////
//定义位图信息
BITMAPINFO BInfo;
BInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
BInfo.bmiHeader.biWidth=bitmap.bmWidth;
BInfo.bmiHeader.biHeight=bitmap.bmHeight;
BInfo.bmiHeader.biPlanes=1;
BInfo.bmiHeader.biBitCount=32;//这里是位图的颜色位数,如果你的位图不是真彩色的,也就是小于等于8位,那就麻烦了,你还要编程实现BitmapInfo.bmiColors结构,所以建议将位图设计成真彩色的,不要吝惜那点空间!
BInfo.bmiHeader.biCompression=BI_RGB;
BInfo.bmiHeader.biClrUsed=0;
BInfo.bmiHeader.biSizeImage=0;
BInfo.bmiHeader.biXPelsPerMeter=0;
BInfo.bmiHeader.biYPelsPerMeter=0;
BInfo.bmiHeader.biClrImportant=0;
//定义一个位图数据指针
char* pData = new char[bitmap.bmWidthBytes*bitmap.bmHeight];
::GetDIBits(memDC.m_hDC,bmp,0,bitmap.bmHeight,pData,&BInfo,DIB_RGB_COLORS);

CRect rc2;
GetDlgItem(IDC_DT2)->GetWindowRect(&rc2);
ScreenToClient(&rc2);

int ret = StretchDIBits(dc.m_hDC,rc2.left,rc2.top+rc2.Height(),rc2.Width(),-rc2.Height(),
0,0,bitmap.bmWidth,bitmap.bmHeight,pData,&BInfo,DIB_RGB_COLORS,SRCCOPY);//显示桌面位图不正常
...全文
453 5 打赏 收藏 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
shuimx 2011-01-13
  • 打赏
  • 举报
回复
我这样加的
CDC memDC; //定义一个内存画布
memDC.CreateCompatibleDC(&dc);//创建一个兼容的画
CBitmap bmp;
// bmp.LoadBitmap(IDB_BITMAP1);
bmp.CreateCompatibleBitmap(pDeskDC,width,height); //创建兼容位图
memDC.SelectObject(&bmp); //选中位图对象

memDC.BitBlt(0,0,width,height, pDeskDC,width,height,SRCCOPY);还是不行。。。。。
lizhigang34 2011-01-13
  • 打赏
  • 举报
回复
你说显示桌面时全是黑色,我想问题可能在这里:
CDC memDC; //定义一个内存画布
memDC.CreateCompatibleDC(&dc);//创建一个兼容的画
CBitmap bmp;
// bmp.LoadBitmap(IDB_BITMAP1);
bmp.CreateCompatibleBitmap(pDeskDC,width,height); //创建兼容位图
memDC.SelectObject(&bmp); //选中位图对象
//应该再用BitBlt把桌面上的内容复制到memDC
memDC.BitBlt(..., pDeskDC,..);
shuimx 2011-01-13
  • 打赏
  • 举报
回复
我创建一幅图像,可以取出数据。程序写在上面了。
TandyT 2011-01-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lizhigang34 的回复:]
你说显示桌面时全是黑色,我想问题可能在这里:
CDC memDC; //定义一个内存画布
memDC.CreateCompatibleDC(&dc);//创建一个兼容的画
CBitmap bmp;
// bmp.LoadBitmap(IDB_BITMAP1);
bmp.CreateCompatibleBitmap(pDeskDC,width,height); //创建兼容位图
……
[/Quote]


这样还不行的话,你是没成功获取到图像的数据吧,怎么会全是 0 的呢?你自己创建一幅图像试试,可能是你获取桌面图像时出错了
源码链接: https://pan.quark.cn/s/a4b39357ea24 微信小程序是由腾讯公司设计的一种轻量级应用开发平台,主要面向移动设备,旨在为用户带来无需下载安装即可直接使用的应用服务体验。在微信小程序的开发实践中,"模仿美团菜单 swiper分类菜单"是一项常见的技术应用,其目的是达成与美团外卖应用相似的交互模式,使用户能够轻松地浏览和挑选各种商品或服务。 在微信小程序的技术体系中,`swiper`组件属于轮播图功能模块,通常用于呈现多张图片或卡片式的切换界面,能够达成动态滑动展示不同分类菜单的功能。在模拟美团菜单的应用情境下,`swiper`组件一般与`swiper-item`组件协同工作,每一个`swiper-item`对应一个分类,用户可通过左右滑动来切换不同的分类菜单。 为了达成这样的功能,首先需要在微信小程序的`json`配置文档中引入`swiper`组件,并在`wxml`结构文档中构建相应的布局代码,将每个分类以`swiper-item`的形式进行组织。同时,需要在`wxss`样式文档中定义恰当的样式,保证分类菜单的视觉呈现符合设计规范。 接下来,我们将在`js`逻辑文档中处理`swiper`的切换逻辑,通过监听`bindchange`事件来识别当前选中的分类,并根据这一信息动态获取对应的子菜单信息。为了达成类似美团的层级菜单功能,可能还需要借助`picker`或`navigator`组件来展示二级分类或商品详情。 在开发阶段,需要关注以下关键点: 1. 数据绑定:保证数据与界面之间的双向链接准确无误,以便在选择分类时即时更新显示内容。 2. 动态加载:针对大量数据,可能需要采取异步加载机制,防止一次性加载过多内容引发性能瓶颈...

19,463

社区成员

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

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