【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片

  本文主要介绍如何截取电脑桌面并将其保存为bmp图片。

 

1. Bmp图像文件组成

  Bmp是Windows操作系统中的标准图像文件格式。

  Bmp图像文件由四部分组成:

  (1)位图头文件数据结构,包含Bmp图像文件的类型、文件大小等信息。

  (2)位图信息数据结构,包含Bmp图像的宽、高、压缩类型等信息。

  (3)颜色表,该部分可选,有些位图需要,有些位图(如24位真彩色位图)不需要。

  (4)位图数据。

1.1位图头文件数据结构

  位图头文件数据结构包含Bmp图像文件的类型、文件大小等信息,占用14个字节。其结构定义如下:

1 typedef struct tagBITMAPFILEHEADER {
2         WORD    bfType;                  //位图类型(必须为BM)
3         DWORD   bfSize;                  //位图大小
4         WORD    bfReserved1;              //位图保留字
5         WORD    bfReserved2;               //位图保留字
6         DWORD   bfOffBits;                 //位图数据的起始位置
7 } BITMAPFILEHEADER;

  其中,bfType表明了位图类型,必须为BM;bfReserved1和bfReserved2是位图保留字,必须为0;bfOffBits表示了文件头的偏移量,也即位图数据的起始位置。

1.2位图信息数据结构

  位图信息数据结构用于说明位图的尺寸等信息,占用40个字节。其结构定义如下:

 1 typedef struct tagBITMAPINFOHEADER{
 2         DWORD      biSize;                  //本结构体所占用字节数
 3         LONG       biWidth;                   //位图宽度
 4         LONG       biHeight;                //位图高度
 5         WORD       biPlanes;                //位图调色板数量
 6         WORD       biBitCount;               //每个像素所需的位数
 7         DWORD      biCompression;            //位图压缩类型(0不压缩)
 8         DWORD      biSizeImage;             //位图大小
 9         LONG       biXPelsPerMeter;          //位图水平分辨率
10         LONG       biYPelsPerMeter;          //位图垂直分辨率
11         DWORD      biClrUsed;                //位图实际使用的颜色表中的颜色数
12         DWORD      biClrImportant;           //位图显示过程中重要的颜色数
13 } BITMAPINFOHEADER;

  其中,biWidth和biHeight分别表示位图的宽度和位图的高度,均匀像素为单位;biPlanes表示调色板的数量,必须为1;biBitCount表示每个像素所需的位数,其值必须是1(双色)、4(16色)、8(256色)、16(高彩色)或24(真彩色);biCompression表示位图压缩类型,其值必须是0(不压缩)、1(BI_RLE8压缩)或2(BI_RLE4压缩)。

1.3颜色表

  颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构体,定义一种颜色。RGBQUAD结构体定义如下:

1 typedef struct tagRGBQUAD {
2         BYTE    rgbBlue;                    //蓝色
3         BYTE    rgbGreen;                   //绿色
4         BYTE    rgbRed;                     //红色
5         BYTE    rgbReserved;                //保留值
6 } RGBQUAD;

  颜色表中RGBQUAD结构数据的个数由biBitCount来确定,当biBitCount为1,4,8时,分别有2,16,256个表项,当biBitCount为24,没有颜色表项。

1.4位图数据

  位图数据记录了位图的每一个像素值,记录顺序是在扫描行内从左到右,扫描行之间从下到上。当biBitCount为1时,8个像素占1个字节;当biBitCount为4时,2个像素占1个字节;当biBitCount为8时,1个像素占1个字节;当biBitCount为24时,1个像素占3个字节(顺序为B、G、R)。

 

2.编程示例

  如下的代码示例了如何截取电脑桌面并将其保存为bmp图片。

 1 /*
 2  * 函数功能 : 该函数用于截取电脑桌面并将其保存为bmp图片
 3  * 备    注 : 
 4  * 作    者 : 博客园 依旧淡然
 5  */
 6 void CCopyScreenDlg:: CopyScreenToBitmap () 
 7 {
 8     //创建桌面设备环境对象
 9     CDC screenDC;
10     screenDC.CreateDC("DISPLAY", NULL, NULL, NULL);
11     
12     //创建桌面位图对象
13     CBitmap bmp;
14     int nWidth = GetSystemMetrics(SM_CXSCREEN);                    //桌面宽度
15     int nHeight = GetSystemMetrics(SM_CYSCREEN);                  //桌面高度
16     bmp.CreateCompatibleBitmap(&screenDC, nWidth, nHeight);
17     
18     //创建内存设备环境对象
19     CDC memDC;
20     memDC.CreateCompatibleDC(&screenDC);
21     memDC.SelectObject(&bmp);
22     memDC.BitBlt(0, 0, nWidth, nHeight, &screenDC, 0, 0, SRCCOPY);
23     
24     //填充位图数据
25     BITMAP bm;
26     bmp.GetBitmap(&bm);
27     DWORD bmSize = bm.bmWidthBytes*bm.bmHeight;                    //位图数据大小
28     LPSTR bmData = (LPSTR)GlobalAlloc(GPTR, bmSize);              //位图数据
29 
30     //填充位图头文件数据结构体
31     BITMAPFILEHEADER hdr;
32     hdr.bfType = (WORD)('M'<<8)|'B';                              //位图类型(必须为BM)
33     hdr.bfSize = 54+bmSize;                                        //位图大小
34     hdr.bfReserved1 = 0;                                          //位图保留字
35     hdr.bfReserved2 = 0;                                          //位图保留字
36     hdr.bfOffBits = 54;                                            //位图数据的起始位置
37 
38     //填充位图信息数据结构体
39     BITMAPINFOHEADER bmpInfoHdr;
40     bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER);                 //本结构体所占用字节数
41     bmpInfoHdr.biWidth = bm.bmWidth;                              //位图宽度
42     bmpInfoHdr.biHeight = bm.bmHeight;                            //位图高度
43     bmpInfoHdr.biPlanes = bm.bmPlanes;                            //位图调色板数量
44     bmpInfoHdr.biBitCount = bm.bmBitsPixel;                        //每个像素所需的位数
45     bmpInfoHdr.biCompression = 0;                                 //位图压缩类型(0不压缩)
46     bmpInfoHdr.biSizeImage = bmSize;                              //位图大小
47     bmpInfoHdr.biXPelsPerMeter = 0;                                //位图水平分辨率
48     bmpInfoHdr.biYPelsPerMeter = 0;                                //位图垂直分辨率
49     bmpInfoHdr.biClrUsed = 0;                                     //位图实际使用的颜色表中的颜色数
50     bmpInfoHdr.biClrImportant = 0;                                //位图显示过程中重要的颜色数
51 
52     //指定颜色表由RGB三个直接值构成
53     GetDIBits(screenDC, bmp, 0, bmpInfoHdr.biHeight, bmData, (BITMAPINFO*)&bmpInfoHdr, DIB_RGB_COLORS);
54 
55     //保存bmp图片
56     CFile file;
57     if(file.Open("temp.bmp", CFile::modeCreate|CFile::modeWrite))
58     {
59         file.WriteHuge(&hdr, sizeof(BITMAPFILEHEADER));            //写入位图头文件数据
60         file.WriteHuge(&bmpInfoHdr, sizeof(BITMAPINFOHEADER));     //写入位图信息数据
61         file.WriteHuge(bmData, bmSize);                            //写入位图数据
62         file.Close();
63     }
64 }

 

posted @ 2015-04-20 22:18  依旧淡然  阅读(1274)  评论(0编辑  收藏