MFC绘图总结-屏幕截屏,获取DIB/DDB图形Pixel

1.       对当前的Screen进行Copy屏幕,获取BITMAP

对当前屏幕Copy,需要获取当前屏幕的HDC,

一种是直接从屏幕DC抓原始图。

一种是然后使用兼容MemDC进行抓图,然后可以附加图形的相关处理,如调整大小,如把鼠标绘制上去等。

(注:如果是对当前程序Copy屏幕的话,传入GetDC参数使用 this->getsafehwnd())

(注:如果对指定窗口Copy屏幕的话,可以用Spy++获取窗口HWND,然后传入GetDC)

对于从程序抓原始图的方式比式比较简单,例如:

// 获取当前屏幕HDC

HDC hScreenDC = ::GetDC(NULL);

// 直接获取当前DC对应的BITMAP

HBITMAP hBmp = (HBITMAP) GetCurrentObject (hScreen, OBJ_BITMAP);

对于使用兼容DC抓图的例子如下,例如:

// 获取当前屏幕HDC
HDC hScreenDC = ::GetDC(NULL);
// 创建兼容HDC
HDC 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来保存图形。

例如:

// 绑定hbmp

CBitmap 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

// 初始化空白PBITMAPINFO

LPBITMAPINFO 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;
时间: 2024-10-01 07:21:19

MFC绘图总结-屏幕截屏,获取DIB/DDB图形Pixel的相关文章

Java邮件发送与屏幕截屏

前几天七夕情人节孤独寂寞的程序猿闲来没事,花了一两个小时写了个小Demo主要实现Java的Mail发送功能和桌面截屏功能. 首先让我们先看看Java sendMail邮件发送和桌面屏幕截屏功能是怎么实现的基础知识. 一.Java  SendMail邮件发送 首先让我们来看看邮件发送的原理图: JavaMail 是一套sun 提供开发邮件收发程序API,JavaMail编写程序就是邮件客户端程序(和outlook.foxmail功能类似) * JavaMail开发需要类库 javamail API

iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)

iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 保存至相册只需将方法saveImage中的代码替换即可 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, 0.0); [self.view.layer renderInContext:UIGraphicsGetCur

超好用的滚动屏幕截屏工具FastStone Capture

对于超级喜欢整理的技术控,一看到比较好技术文章就想收集下来,单纯的记录网页,又怕作者删除,我只能选择截图,可是有许多文章特别长,直到使用FastStone Capture截图工具,终于可以快速收集这些技术文章了. 1.截图工具是这样的 2.比较好用的滚动截屏使用方法: 图中第六个图标. 1)点击后,可以拖动窗口进行大范围的截图,比如可以将浏览器的网页做为截图对象,截取时,点击选取滚动条箭头就可以完成截图,ESC中断截图滚动! 2)在选定滚动截图图标后还可以按ctrl键进行滚动区域的选择. 3.图

使用selenium截屏获取验证码

self.driver = Chrome(CHROME_DRIVER) #初始化对象self.driver.set_window_size(1280, 1024) #设置窗口大小 self.driver.execute_script( 'localStorage.setItem("pre_appadmin_login_2541044284@qq.com",JSON.stringify(%s))' % self.local_storage)#设置localStorage本地缓存 self

ios xcode真机调试获取屏幕截屏

非常多时候我们须要在调试的过程中把手机屏幕截图发给其它人看,在android开发中我们能够非常方便的截图保存.而xcode开发ios的时候发现这个需求却如此困难.网上大部分都是介绍的以下这个方案.可是我在xcode 6.2中却不能使用. 1.进入xcode 2.右上角的[Origanizer] 3.左边project下的[Screenshots] 4.xcode右下角的[New Screenshots] 而我无意中发现还有一种办法是可行的 1.进入xcode 2.点击上面一排的Window 3.

delphi 屏幕截屏

function GetScreenAll: TBitmap; // 截取全屏 var C: TCanvas; begin C := TCanvas.Create; result := TBitmap.Create; result.Width := Screen.Width; result.Height := Screen.Height; C.Handle := GetDC(0); // 获取屏幕的设备上下文句柄,并拷贝 result.Canvas.CopyRect(Rect(0, 0, scr

C# 实现屏幕截屏

//屏幕宽            int iWidth = Screen.PrimaryScreen.Bounds.Width;            //屏幕高            int iHeight = Screen.PrimaryScreen.Bounds.Height;            //按照屏幕宽高创建位图            Image img = new Bitmap(iWidth, iHeight);            //从一个继承自Image类的对象中创建

iOS当前屏幕截屏

需求描述: 有两个ViewController 我们记做 A.B ,其中B controller只是显示下半部分: 如下图效果: 实现这种的方案很多,可以用添加View方法,  也可以用UIWindows 来实现. 但是我这边是想用presentViewController 实现,但是A present  B之后,之前的A就会消失,不会和B 覆盖显示,因此就相当了截取A试图之后在present B. 具体看看实现方案吧: 方法一: 这个方法获取的到图片不会失真 1 -(UIImage *)cap

iOS屏幕截屏

#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //开启位图上下文 UIGraphicsBeginImageContext