【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 }