`
java-mans
  • 浏览: 11391178 次
文章分类
社区版块
存档分类
最新评论

将HDC保存为BMP文件

 
阅读更多

//========================================================================
//TITLE:
// 将HDC保存为BMP文件
//AUTHOR:
// norains
//DATE:
// Friday 25-September-2009
//Environment:
// WINDOWS CE 5.0
//========================================================================

HDC在MSDN中的全称为:The handle of device context。通常,我们都是用来做相应的显示操作。

熟悉WIN32的朋友对于其应该不会陌生,经常采用GetDC,GetWindowDC等等来获取其句柄。而用得最多的,可能就是BeginPaint,如:

使用起来非常简单,但如果想将其内容保存为普通的图像文档,可就没那么容易。确切地说,在只知道HDC句柄的情况下,我们是无法保存其内容的;但我们可以剑走偏锋,将HDC的内容写到一个缓存中,然后我们再保存该缓存的内容即可。

听起来很简单,却又像很复杂,不是么?没关系,我们现在一步一步来。


首先,我们需要一个HDC的句柄。如同前面所说,你可以有多种方法,比如GetDC,GetWindowDC,甚至是CreateDC。反正呢,你用什么方法我不管,我只要有一个HDC的句柄就好了。

有了HDC的句柄,接下来我们所需要做的是,知道这HDC的大小,也就是宽度和长度。这个不难,我们只要简单地调用GetDeviceCaps,然后参数给予HORZRES或VERTRES即可:

为什么要知道大小呢?因为我们要用它来创建缓存。而这缓存,说白了,其实就是一个BMP格式的数据结构而已。

为了创建这个关键的缓存,我们必须调用CreateDIBSection函数,而该函数形参又用到BITMAPINFOHEADER,所以我们的一切,就先从填充该结构体开始。

该结构体定义如下:

结构体里面还有一个BITMAPINFOHEADER,其定义如下:

这么多变量,是不是有点头晕?大可不必紧张,其实我们只需要填充其中几个,其它统统置为0即可:

一切从最简单做起,对于BMP而言,最简单的自然是24位位图,这就是为什么biPlanes和biBitCount分别设置为1和24的原因。

填充完BITMAPINFO结构,我们还是不能马上调用CreateDIBSection,因为形参中还有一个HDC。虽然我们可以直接采用已知的HDC句柄,但接下来还要将创建的HBITMAP和HDC相连接,所以我们还是先创建一个缓存DC:

一切准备就绪之后,就调用CreateDIBSection吧:

pData是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。

将HBITMAP和HDC结合:

至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:

这里其实还有一个小技巧,如果你是想绘制HDC的某个区域,你只需要用StretchBlt替代即可:

喜欢追究问题的你,也许会发现,在调用该函数之后,pData所指向的内存缓冲区已经改变。是的,没错,这些改变的数据就是我们所需要的。接下来我们所需要做的仅仅是,将这数据按BMP文件的格式,保存下来即可。

BMP文件格式其实很简单,最开始是文件头信息,然后是图片信息,接下来是数据。我们只需要按照这格式,顺序将数据写入即可。

文件头信息和图片信息,微软已经为我们定义好了相应的结构体:

BMP信息:

文件头信息:

我们首先填充这两个结构体数值:

接下来的事情,估计大家都轻车熟路了。创建文件,然后写入数据,保存,完毕。

文章的最后,是参考源代码:


一共有三个WriteBmp函数,使用上非常简单。

比如,我想保存一个HDC,只需要简单地调用:

如果想保存HDC的某一个部分,同样也很简单:

这个函数还能做到一个很有意思的功能,就是截取屏幕。对于屏幕来说,也是一个HDC,我们只要获取屏幕的HDC句柄,剩下的就没有什么难度了:

分享到:
评论

相关推荐

    WinCE实现屏幕截图并保存为BMP文件

    WinCE实现屏幕截图并保存为BMP文件,通过句柄获得HDC并保存为BMP文件,从而实现全屏截图以及窗口截图,详细内容:http://blog.csdn.net/wyunteng/archive/2011/04/30/6375381.aspx

    VC++实现View内容保存为图片的方法

    我们在单文档应用程序中,经常需要将View中的内容保存为各种格式的图片文件,以便打印。乍一看,可能不知道从哪里下手,其实主要就是用到Bitmap的save方法,如: HDC hmemDC = ::CreateCompatibleDC( hdc ); ...

    BitmapDisplay

    readMyDoc BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,...2) 保存位图为磁盘文件 3) 读取位图并显示在VC界面上

    C++实现屏幕截图

    上回分享了一个全屏截图的代码,保存为BMP,参考:C++实现屏幕截图(全屏截图) 实际使用的过程中我发现截图文件实在大,无奈又整成了PNG截图,现在分享出来。 MakePNG.h //MakePNG.h #pragma once #include ...

    摄像头组件调用示例

    保存的图片格式为bmp格式。 包含包“Snapshot526.h” 并在stdafx.h中或调用的模块中加入 #pragma comment(lib, "Camera526.lib") 然后在操作开始摄像头抓拍操作事件中 CSnapshot526 snapshot; CString ...

    windows平台上支持BITMAPCOREHEADER、BITMAPINFOHEADER、BITMAPV4HEADER、BITMAPV5HEADER四种类型位图的类库

    //保存到文件 该类的头文件接口大致如下: class DibBitmap { BITMAPFILEHEADER* m_pbmfh; DWORD m_size;//保存m_pbmfh中malloc出来的内存大小,即是capacity//不为0时保证图像是可以处理的 public: enum BmType...

    类似画图板的小程序-windows

    功能主要有: 手绘线、简单图形、文字输入、图块拖放、重复撤销、画面缩放、打开保存图片文件,另外为了直接从数据库或者XML中存取图片,另外还提供了从Base64编码存取图片的接口,其他还实现了和画图板同样效果的...

    Led 显示 类 数码管 数码 数字

    背景位图的向量m_vecBkSave不断扩大,而实际上保存的位图将没有作用且浪费大量内存! 如: void CLEDView::OnPaint() { CPaintDC dc(this); OnShow(); //不断的以不同的...

    屏幕截图的源代码(用按键机器人开发的)

    {保存临时位图到文件} SetObj(sImageTemp,'Free'); {释放临时位图} {SetObj(g.sForm,'Text='+'CopyRect='+sRectTemp+','+g.sImageDes+','+sRect);} ]; [打开保存对话框; sSaveDialog:=SetObj(g.sForm,'...

    中控指纹识别软件开发包Biokey SDK3.0 PRO

    MessageBox 0, "文件保存成功(" + sFileName + ")!", "", 0 End Sub Private Sub cmdVerify_Click() If ZKFPEngX1.IsRegister Then ZKFPEngX1.CancelEnroll End If ZKFPEngX1.BeginCapture StatusBar.Caption...

    C++MFC教程

    3、开发注重交互并且文件读写复杂的的简单应用程序可以利用以CFormView为基础视的单文档视结构。 4、利用对话框得到用户输入的数据,在等级提高后可使用就地输入。 5、在对多文档要求不强烈时尽量避免多文档视结构,...

Global site tag (gtag.js) - Google Analytics