抓屏 和 像素点 操作 的问题

ChangeMyHead 2008-10-20 12:08:28
1、我在做一个抓屏软件,但是要对其中的大部分像素点进行操作。
2、我如果直接在屏幕DC上操作,速度很慢,所以是通过BitBlt将屏幕DC的东西Copy出来,然后GetPixel取得像素点操作,处理完成后用SetPixel写入DC。
3、问题是,直接操作屏幕DC可以,但Copy出来,GetPixel就得不到像素值,请高手帮忙分析下。
4、下面代码是我简化后的代码。
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX=0, nY=0, nX2=300, nY2=300;
// 选定区域坐标
int nWidth = 300, nHeight=300;

//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);

//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);

// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);

// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); //我希望是,将屏幕信息Copy到hMemDC里面,然后我在对像素进行操作

//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);

//临时DC,为了存储临时位图
HDC hDlgDc = GetDC()->m_hDC;

//比较位图
for( int i=0; i<200; i++)
for( int j=0; j<200; j++)
{
unsigned long lLeftPoint = GetPixel( hMemDC , i , j ); //这里得到的像素值不对
//unsigned long lRighPoint = GetPixel( hScrDC , i , j ); //如果用这个,可以显示,但整个操作就会太慢

SetPixel( hDlgDc , i , j , lLeftPoint );// lRighPoint
}

//将位图显示到对话框
BitBlt( GetDC()->m_hDC , 0 , 0 , 200 , 200 , hDlgDc , 0, 0, SRCCOPY);

//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
...全文
174 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wltg2001 2008-10-20
  • 打赏
  • 举报
回复
GetDibBits 是针对DIB的,楼主抓取的图是屏幕图,就是DDB,用这个函数不合适。
=========================
API中没有GetDibBits这个函数吧,应该是GetDIBits吧,另外GetDIBits并不像上面说的针对DIB的,它是指将DDB的数据转化成DIB数据存到一数据区中去,一般将DDB位图转成位图文件就要用这个。楼主也可以用GetBitmapBits,不过这个API已经被GetDIBits代替了。
littleplane 2008-10-20
  • 打赏
  • 举报
回复
看看我的资源 http://download.csdn.net/source/606844
里面有一个CBmpFile,可以对每一个像素操作
Soyokaze 2008-10-20
  • 打赏
  • 举报
回复
==〉5楼
GetDibBits 是针对DIB的,楼主抓取的图是屏幕图,就是DDB,用这个函数不合适。
Soyokaze 2008-10-20
  • 打赏
  • 举报
回复
的确,GetPixel 和 SetPixel 很慢的,绝对不应该在处理大块的位图数据中采用。应该采用 GetDIBits 直接操作内存数据。
E_xplorer 2008-10-20
  • 打赏
  • 举报
回复
同意3楼的说法

//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); //多余的
hbdycnm 2008-10-20
  • 打赏
  • 举报
回复
//要对所有点操作,最好用GetDibBits直接对位图的原始数据进行操作。
//网上有cdib类,可以直接用,直接抓屏,处理数据都有, 自己找找看。
scq2099yt 2008-10-20
  • 打赏
  • 举报
回复
用GetDIBits取得原始数据,然后对相应数据区进行处理在速度上要快得多。
dirdirdir3 2008-10-20
  • 打赏
  • 举报
回复
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); //我希望是,将屏幕信息Copy到hMemDC里面,然后我在对像素进行操作

//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);

//临时DC,为了存储临时位图
HDC hDlgDc = GetDC()->m_hDC;



去掉hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); 或者放到最后
你选旧的bitmap想取什么数据????????
wltg2001 2008-10-20
  • 打赏
  • 举报
回复
用GetDIBits取得原始数据,然后对相应数据区进行处理在速度上要快得多。
嵌云阁主 2008-10-20
  • 打赏
  • 举报
回复
要对所有点操作,最好用GetDibBits直接对位图的原始数据进行操作。
cnzdgs 2008-10-20
  • 打赏
  • 举报
回复
GetDC用完后需要ReleaseDC。
另外,你这种处理方法也一样慢,可以参考大家的说法,改成DIB操作。

19,472

社区成员

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

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