標籤:
本文主要介紹如何截取電腦案頭並將其儲存為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 }
【VC++技術雜談006】截取電腦案頭並將其儲存為bmp圖片