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

1. Bmp图像文件组成

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

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

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

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

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

  (4)位图数据。

1.1位图头文件数据结构

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

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

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

1.2位图信息数据结构

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

 typedef struct tagBITMAPINFOHEADER{
DWORD biSize;   //本结构体所占用字节数
LONG biWidth; //位图宽度
LONG biHeight;    //位图高度
WORD biPlanes;    //位图调色板数量
WORD biBitCount; //每个像素所需的位数
DWORD biCompression; //位图压缩类型(0不压缩)
DWORD biSizeImage;    //位图大小
LONG biXPelsPerMeter; //位图水平分辨率
LONG biYPelsPerMeter; //位图垂直分辨率
DWORD biClrUsed; //位图实际使用的颜色表中的颜色数
DWORD biClrImportant; //位图显示过程中重要的颜色数
} 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结构体定义如下:

 typedef struct tagRGBQUAD {
BYTE rgbBlue; //蓝色
BYTE rgbGreen; //绿色
BYTE rgbRed; //红色
BYTE rgbReserved; //保留值
} 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图片。

 /*
* 函数功能 : 该函数用于截取电脑桌面并将其保存为bmp图片
* 备 注 :
* 作 者 : 博客园 依旧淡然
*/
void CCopyScreenDlg:: CopyScreenToBitmap ()
{
//创建桌面设备环境对象
CDC screenDC;
screenDC.CreateDC("DISPLAY", NULL, NULL, NULL); //创建桌面位图对象
CBitmap bmp;
int nWidth = GetSystemMetrics(SM_CXSCREEN); //桌面宽度
int nHeight = GetSystemMetrics(SM_CYSCREEN);   //桌面高度
bmp.CreateCompatibleBitmap(&screenDC, nWidth, nHeight); //创建内存设备环境对象
CDC memDC;
memDC.CreateCompatibleDC(&screenDC);
memDC.SelectObject(&bmp);
memDC.BitBlt(, , nWidth, nHeight, &screenDC, , , SRCCOPY); //填充位图数据
BITMAP bm;
bmp.GetBitmap(&bm);
DWORD bmSize = bm.bmWidthBytes*bm.bmHeight; //位图数据大小
LPSTR bmData = (LPSTR)GlobalAlloc(GPTR, bmSize);   //位图数据 //填充位图头文件数据结构体
BITMAPFILEHEADER hdr;
hdr.bfType = (WORD)('M'<<)|'B';   //位图类型(必须为BM)
hdr.bfSize = +bmSize; //位图大小
hdr.bfReserved1 = ;   //位图保留字
hdr.bfReserved2 = ;   //位图保留字
hdr.bfOffBits = ; //位图数据的起始位置 //填充位图信息数据结构体
BITMAPINFOHEADER bmpInfoHdr;
bmpInfoHdr.biSize = sizeof(BITMAPINFOHEADER); //本结构体所占用字节数
bmpInfoHdr.biWidth = bm.bmWidth; //位图宽度
bmpInfoHdr.biHeight = bm.bmHeight; //位图高度
bmpInfoHdr.biPlanes = bm.bmPlanes; //位图调色板数量
bmpInfoHdr.biBitCount = bm.bmBitsPixel; //每个像素所需的位数
bmpInfoHdr.biCompression = ; //位图压缩类型(0不压缩)
bmpInfoHdr.biSizeImage = bmSize; //位图大小
bmpInfoHdr.biXPelsPerMeter = ; //位图水平分辨率
bmpInfoHdr.biYPelsPerMeter = ; //位图垂直分辨率
bmpInfoHdr.biClrUsed = ; //位图实际使用的颜色表中的颜色数
bmpInfoHdr.biClrImportant = ; //位图显示过程中重要的颜色数 //指定颜色表由RGB三个直接值构成
GetDIBits(screenDC, bmp, , bmpInfoHdr.biHeight, bmData, (BITMAPINFO*)&bmpInfoHdr, DIB_RGB_COLORS); //保存bmp图片
CFile file;
if(file.Open("temp.bmp", CFile::modeCreate|CFile::modeWrite))
{
file.WriteHuge(&hdr, sizeof(BITMAPFILEHEADER)); //写入位图头文件数据
file.WriteHuge(&bmpInfoHdr, sizeof(BITMAPINFOHEADER)); //写入位图信息数据
file.WriteHuge(bmData, bmSize); //写入位图数据
file.Close();
}
}
05-08 15:37