首页 > 代码库 > MFC绘图总结-屏幕截屏,获取DIB/DDB图形Pixel
MFC绘图总结-屏幕截屏,获取DIB/DDB图形Pixel
1. 对当前的Screen进行Copy屏幕,获取BITMAP
对当前屏幕Copy,需要获取当前屏幕的HDC,
一种是直接从屏幕DC抓原始图。
一种是然后使用兼容MemDC进行抓图,然后可以附加图形的相关处理,如调整大小,如把鼠标绘制上去等。
(注:如果是对当前程序Copy屏幕的话,传入GetDC参数使用 this->getsafehwnd())
(注:如果对指定窗口Copy屏幕的话,可以用Spy++获取窗口HWND,然后传入GetDC)
对于从程序抓原始图的方式比式比较简单,例如:
// 获取当前屏幕HDCHDC hScreenDC = ::GetDC(NULL);// 直接获取当前DC对应的BITMAPHBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP);
对于使用兼容DC抓图的例子如下,例如:
// 获取当前屏幕HDCHDC hScreenDC = ::GetDC(NULL);// 创建兼容HDCHDC hMemDC = ::CreateCompatibleDC(hScreenDC)// 创建兼容位图HBITMAP hbm = CreateCompatibleBitmap(hScreenDC, width, height);// 为MemDC选中兼容为图HBITMAP oldbm = (HBITMAP) SelectObject(hMemDC, hbm);// 复制图片像素内容BitBlt(hMemDC, 0, 0, width, height, hScreenDC, left, top, SRCCOPY); // 如果需要绘制鼠标信息的话{//Draw the Cursor ICONINFO iconinfo ; BOOL ret; ret = GetIconInfo( hcur, &iconinfo ); if (ret) { xPoint.x -= iconinfo.xHotspot; xPoint.y -= iconinfo.yHotspot; //need to delete the hbmMask and hbmColor bitmaps //otherwise the program will crash after a while after running out of resource if (iconinfo.hbmMask) DeleteObject(iconinfo.hbmMask); if (iconinfo.hbmColor) DeleteObject(iconinfo.hbmColor); } ::DrawIcon( hMemDC, xPoint.x, xPoint.y, hcur); }// 设置回原有的DC绑定位图SelectObject(hMemDC,oldbm);
2. 获取DDB图形Pixel
DDB-Device dependency bitmap设备依赖图形
因为当前Bitmap都是通过DC获取的,所以都是DDB类型的图形。
通过CBitmap的函数GetBitmapBits,获取到相关bits内容,或者也可以使用GetBitmap获取整个BITMAP结构信息。
但获取到的这个pixel信息是和当前device相关的,例如device是24位色/32位色/自下而上绘制的/使用颜色掩码,则获取到的pixel也是这种的,
注: 此处CBitmap为DDB图形,不能使用CImage进行CImage::GetBits获取Pixel,详见CImage:: IsDIBSection说明。同时,如果要保存图形的话,可以借用CImage:: Save来保存图形。
例如:
// 绑定hbmpCBitmap bitmap;Bitmap.attach(hBmp);// 申请内存byte pBuffer = new [width * 4 * height];// 获取bits信息Bitmap. GetBitmapBits(pBuffer);
3. 获取DIB图形Pixel
DIB-Device Independency Bitmap设备无关图形
这类图形,本身结构中具备了图形颜色位数/颜色表/颜色掩码说明相关的信息,所以就可以不依赖于从社备中查询这些信息,也称为设备无关图形。
从HBitmap获取DIB图形的函数常用GetDIBits。
GetDIBBits一方面可以用于查询出当前设备的结构信息,填入DIB头信息BITMAPINFO说明中;
另一方面,可以指定BITMAPINFO/指定图形格式,从Bitmap中转换出指定格式的图形信息。
所以它的用法有两种:
1. 一种是获取Device中的格式,然后填入到BItmapInfo,然后基于该BitmapInfo,获取Pixel信息
2. 另一种是,直接指定Bitmapinfo,获取基于指定格式转换后Pixsel信息
例如,我们兼或考虑这两种,先获取设备BitmapInfo,然后对格式进行修改,再获取修改格式后的图形Pixel
// 初始化空白PBITMAPINFOLPBITMAPINFO lpBitmapInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD));memset(lpBitmapInfo, 0, sizeof(BITMAPINFO)+256 * sizeof(RGBQUAD));lpBitmapInfo->bmiHeader.biSize = sizeof(lpBitmapInfo->bmiHeader);// lpvBits使用NULL查询位图DIB信息if (GetDIBits(hMemDC, hBmp, 0, 0, NULL, lpBitmapInfo, DIB_RGB_COLORS)){ // 修改格式,使用修改后的格式获数据Pixel数据lpBitmapInfo->bmiHeader.biCompression = BI_RGB; lpBitmapInfo->bmiHeader.biBitCount = 24; // 查询位图DIB信息 GetDIBits(hMemDC, (HBITMAP)cBitmap.GetSafeHandle(), 0, nHeight, pBuffer, lpBitmapInfo, DIB_RGB_COLORS);}// 处理完毕删除头信息delete lpBitmapInfo;
MFC绘图总结-屏幕截屏,获取DIB/DDB图形Pixel