VC屏幕截图并保存为bmp文件
生活随笔
收集整理的這篇文章主要介紹了
VC屏幕截图并保存为bmp文件
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
保存抓圖的簡單實現(xiàn)
實現(xiàn)類似的抓屏功能(簡單的截圖功能 )
其實只要兩個函數(shù)就行了,以下從網(wǎng)上摘抄的一段代碼的改寫, 算是原創(chuàng)吧
(http://www.wenyiwen.cn/a24/how161448.htm):
函數(shù)1: CopyScreenToBitmap //將屏幕指定區(qū)域存成圖片
HBITMAP CxxxDlg::CopyScreenToBitmap(LPRECT lpRect) //lpRect? 代表選定區(qū)域
{
?HDC hScrDC, hMemDC; ??
?//? 屏幕和內(nèi)存設備描述表
?HBITMAP hBitmap,hOldBitmap; ??
?//? 位圖句柄
?int nX, nY, nX2, nY2; ??
?//? 選定區(qū)域坐標
?int nWidth, nHeight; ??
?//? 位圖寬度和高度
?int xScrn, yScrn; ??
?//? 屏幕分辨率
?//? 確保選定區(qū)域不為空矩形
?if (IsRectEmpty(lpRect))
? return NULL;
?// 為屏幕創(chuàng)建設備描述表
?hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
?// 為屏幕設備描述表創(chuàng)建兼容的內(nèi)存設備描述表
?hMemDC = CreateCompatibleDC(hScrDC);
?//? 獲得選定區(qū)域坐標
?nX = lpRect->left;
?nY = lpRect->top;
?nX2 = lpRect->right;
?nY2 = lpRect->bottom;
?//? 獲得屏幕分辨率
?xScrn = GetDeviceCaps(hScrDC, HORZRES);
?yScrn = GetDeviceCaps(hScrDC, VERTRES);
?// 確保選定區(qū)域是可見的
?if (nX < 0)
? nX = 0;
?if (nY < 0)
? nY = 0;
?if (nX2 > xScrn)
? nX2 = xScrn;
?if (nY2 > yScrn)
? nY2 = yScrn;
?nWidth = nX2 - nX;
?nHeight = nY2 - nY;
?//? 創(chuàng)建一個與屏幕設備描述表兼容的位圖
?hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
?//? 把新位圖選到內(nèi)存設備描述表中
?hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
?//? 把屏幕設備描述表拷貝到內(nèi)存設備描述表中
?BitBlt(hMemDC,0,0, nWidth,nHeight,hScrDC, nX, nY, SRCCOPY);
?// 得到屏幕位圖的句柄
?hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
?// 清除
?DeleteDC(hScrDC);
?DeleteDC(hMemDC);
?//? 返回位圖句柄
?return hBitmap;
}
?
函數(shù)2 : SaveBitmapToFile 將圖片存成文件
int CxxxDlg::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName) //hBitmap? 為剛才的屏幕位圖句柄
{ //lpFileName? 為位圖文件名
?HDC hDC; ??
? // 設備描述表
?int iBits; ??
?// 當前顯示分辨率下每個像素所占字節(jié)數(shù)
?WORD wBitCount; ??
? // 位圖中每個像素所占字節(jié)數(shù)
?// 定義調(diào)色板大小, 位圖中像素字節(jié)大小 , 位圖文件大小 , 寫入文件字節(jié)數(shù)
?DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize, dwWritten;
?BITMAP Bitmap; ??
?// 位圖屬性結(jié)構(gòu)
?BITMAPFILEHEADER bmfHdr; ??
?// 位圖文件頭結(jié)構(gòu)
?BITMAPINFOHEADER bi; ??
?// 位圖信息頭結(jié)構(gòu)
?LPBITMAPINFOHEADER lpbi; ??
?// 指向位圖信息頭結(jié)構(gòu)
? HANDLE fh, hDib, hPal;
?HPALETTE hOldPal=NULL;
?// 定義文件,分配內(nèi)存句柄,調(diào)色板句柄
??
?// 計算位圖文件每個像素所占字節(jié)數(shù)
?hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
?iBits = GetDeviceCaps(hDC, BITSPIXEL) *
? GetDeviceCaps(hDC, PLANES);
?DeleteDC(hDC);
?if (iBits <= 1)
? wBitCount = 1;
?else if (iBits <= 4)
? wBitCount = 4;
?else if (iBits <= 8)
? wBitCount = 8;
?else if (iBits <= 24)
? wBitCount = 24;
else
? wBitCount = 32;
?// 計算調(diào)色板大小
?if (wBitCount <= 8)
? dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);
??
?// 設置位圖信息頭結(jié)構(gòu)
?GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
?bi.biSize = sizeof(BITMAPINFOHEADER);
?bi.biWidth = Bitmap.bmWidth;
?bi.biHeight = Bitmap.bmHeight;
?bi.biPlanes = 1;
?bi.biBitCount = wBitCount;
?bi.biCompression = BI_RGB;
?bi.biSizeImage = 0;
?bi.biXPelsPerMeter = 0;
?bi.biYPelsPerMeter = 0;
?bi.biClrUsed = 0;
?bi.biClrImportant = 0;
??
?dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;
?// 為位圖內(nèi)容分配內(nèi)存
/*xxxxxxxx 計算位圖大小分解一下(解釋一下上面的語句 )xxxxxxxxxxxxxxxxxxxx??
//每個掃描行所占的字節(jié)數(shù)應該為4的整數(shù)倍,具體算法為 :
?int biWidth = (Bitmap.bmWidth*wBitCount) / 32;
?if((Bitmap.bmWidth*wBitCount) % 32)
? biWidth++; //不是整數(shù)倍的加 1
?biWidth *= 4;//到這里,計算得到的為每個掃描行的字節(jié)數(shù)。
?dwBmBitsSize = biWidth * Bitmap.bmHeight;// 得到大小
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
?hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
?lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
?*lpbi = bi;
?//? 處理調(diào)色板 ???
?hPal = GetStockObject(DEFAULT_PALETTE);
?if (hPal)
?{
? hDC = ::GetDC(NULL);
? hOldPal=SelectPalette(hDC,(HPALETTE)hPal,FALSE);
? RealizePalette(hDC);
?}
?// 獲取該調(diào)色板下新的像素值
?GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, (BITMAPINFO *)lpbi,DIB_RGB_COLORS);
?// 恢復調(diào)色板 ???
?if (hOldPal)
?{
? SelectPalette(hDC, hOldPal, TRUE);
? RealizePalette(hDC);
? ::ReleaseDC(NULL, hDC);
?}
?//創(chuàng)建位圖文件 ???
?fh=CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
?if (fh==INVALID_HANDLE_VALUE)
? return FALSE;
?// 設置位圖文件頭
?bmfHdr.bfType = 0x4D42; // "BM"
?dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;??
?bmfHdr.bfSize = dwDIBSize;
?bmfHdr.bfReserved1 = 0;
?bmfHdr.bfReserved2 = 0;
?bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;
?//? 寫入位圖文件頭
?WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
?//? 寫入位圖文件其余內(nèi)容
? WriteFile(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize , &dwWritten, NULL);
?// 清除 ???
?GlobalUnlock(hDib);
?GlobalFree(hDib);
?CloseHandle(fh);
?return TRUE;
}
3.使用舉例 :
1> 截取保存當前運行程序的畫面
CRect rect;
GetWindowRect(&rect);
HBITMAP hMap = CopyScreenToBitmap(rect);
SaveBitmapToFile(hMap,"C:\\seu07201213( 汪洋中的一片葉子 ).bmp");
2> 全屏截圖
CRect rect;
rect.left = 0;
rect.top = 0;
rect.right = GetSystemMetrics(SM_CXSCREEN);
rect.bottom = GetSystemMetrics(SM_CYSCREEN);
HBITMAP hMap = CopyScreenToBitmap(rect);
實現(xiàn)類似的抓屏功能(簡單的截圖功能 )
其實只要兩個函數(shù)就行了,以下從網(wǎng)上摘抄的一段代碼的改寫, 算是原創(chuàng)吧
(http://www.wenyiwen.cn/a24/how161448.htm):
函數(shù)1: CopyScreenToBitmap //將屏幕指定區(qū)域存成圖片
HBITMAP CxxxDlg::CopyScreenToBitmap(LPRECT lpRect) //lpRect? 代表選定區(qū)域
{
?HDC hScrDC, hMemDC; ??
?//? 屏幕和內(nèi)存設備描述表
?HBITMAP hBitmap,hOldBitmap; ??
?//? 位圖句柄
?int nX, nY, nX2, nY2; ??
?//? 選定區(qū)域坐標
?int nWidth, nHeight; ??
?//? 位圖寬度和高度
?int xScrn, yScrn; ??
?//? 屏幕分辨率
?//? 確保選定區(qū)域不為空矩形
?if (IsRectEmpty(lpRect))
? return NULL;
?// 為屏幕創(chuàng)建設備描述表
?hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
?// 為屏幕設備描述表創(chuàng)建兼容的內(nèi)存設備描述表
?hMemDC = CreateCompatibleDC(hScrDC);
?//? 獲得選定區(qū)域坐標
?nX = lpRect->left;
?nY = lpRect->top;
?nX2 = lpRect->right;
?nY2 = lpRect->bottom;
?//? 獲得屏幕分辨率
?xScrn = GetDeviceCaps(hScrDC, HORZRES);
?yScrn = GetDeviceCaps(hScrDC, VERTRES);
?// 確保選定區(qū)域是可見的
?if (nX < 0)
? nX = 0;
?if (nY < 0)
? nY = 0;
?if (nX2 > xScrn)
? nX2 = xScrn;
?if (nY2 > yScrn)
? nY2 = yScrn;
?nWidth = nX2 - nX;
?nHeight = nY2 - nY;
?//? 創(chuàng)建一個與屏幕設備描述表兼容的位圖
?hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
?//? 把新位圖選到內(nèi)存設備描述表中
?hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
?//? 把屏幕設備描述表拷貝到內(nèi)存設備描述表中
?BitBlt(hMemDC,0,0, nWidth,nHeight,hScrDC, nX, nY, SRCCOPY);
?// 得到屏幕位圖的句柄
?hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
?// 清除
?DeleteDC(hScrDC);
?DeleteDC(hMemDC);
?//? 返回位圖句柄
?return hBitmap;
}
?
函數(shù)2 : SaveBitmapToFile 將圖片存成文件
int CxxxDlg::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName) //hBitmap? 為剛才的屏幕位圖句柄
{ //lpFileName? 為位圖文件名
?HDC hDC; ??
? // 設備描述表
?int iBits; ??
?// 當前顯示分辨率下每個像素所占字節(jié)數(shù)
?WORD wBitCount; ??
? // 位圖中每個像素所占字節(jié)數(shù)
?// 定義調(diào)色板大小, 位圖中像素字節(jié)大小 , 位圖文件大小 , 寫入文件字節(jié)數(shù)
?DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize, dwWritten;
?BITMAP Bitmap; ??
?// 位圖屬性結(jié)構(gòu)
?BITMAPFILEHEADER bmfHdr; ??
?// 位圖文件頭結(jié)構(gòu)
?BITMAPINFOHEADER bi; ??
?// 位圖信息頭結(jié)構(gòu)
?LPBITMAPINFOHEADER lpbi; ??
?// 指向位圖信息頭結(jié)構(gòu)
? HANDLE fh, hDib, hPal;
?HPALETTE hOldPal=NULL;
?// 定義文件,分配內(nèi)存句柄,調(diào)色板句柄
??
?// 計算位圖文件每個像素所占字節(jié)數(shù)
?hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
?iBits = GetDeviceCaps(hDC, BITSPIXEL) *
? GetDeviceCaps(hDC, PLANES);
?DeleteDC(hDC);
?if (iBits <= 1)
? wBitCount = 1;
?else if (iBits <= 4)
? wBitCount = 4;
?else if (iBits <= 8)
? wBitCount = 8;
?else if (iBits <= 24)
? wBitCount = 24;
else
? wBitCount = 32;
?// 計算調(diào)色板大小
?if (wBitCount <= 8)
? dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);
??
?// 設置位圖信息頭結(jié)構(gòu)
?GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
?bi.biSize = sizeof(BITMAPINFOHEADER);
?bi.biWidth = Bitmap.bmWidth;
?bi.biHeight = Bitmap.bmHeight;
?bi.biPlanes = 1;
?bi.biBitCount = wBitCount;
?bi.biCompression = BI_RGB;
?bi.biSizeImage = 0;
?bi.biXPelsPerMeter = 0;
?bi.biYPelsPerMeter = 0;
?bi.biClrUsed = 0;
?bi.biClrImportant = 0;
??
?dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;
?// 為位圖內(nèi)容分配內(nèi)存
/*xxxxxxxx 計算位圖大小分解一下(解釋一下上面的語句 )xxxxxxxxxxxxxxxxxxxx??
//每個掃描行所占的字節(jié)數(shù)應該為4的整數(shù)倍,具體算法為 :
?int biWidth = (Bitmap.bmWidth*wBitCount) / 32;
?if((Bitmap.bmWidth*wBitCount) % 32)
? biWidth++; //不是整數(shù)倍的加 1
?biWidth *= 4;//到這里,計算得到的為每個掃描行的字節(jié)數(shù)。
?dwBmBitsSize = biWidth * Bitmap.bmHeight;// 得到大小
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
?hDib = GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));
?lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
?*lpbi = bi;
?//? 處理調(diào)色板 ???
?hPal = GetStockObject(DEFAULT_PALETTE);
?if (hPal)
?{
? hDC = ::GetDC(NULL);
? hOldPal=SelectPalette(hDC,(HPALETTE)hPal,FALSE);
? RealizePalette(hDC);
?}
?// 獲取該調(diào)色板下新的像素值
?GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize, (BITMAPINFO *)lpbi,DIB_RGB_COLORS);
?// 恢復調(diào)色板 ???
?if (hOldPal)
?{
? SelectPalette(hDC, hOldPal, TRUE);
? RealizePalette(hDC);
? ::ReleaseDC(NULL, hDC);
?}
?//創(chuàng)建位圖文件 ???
?fh=CreateFile(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
?if (fh==INVALID_HANDLE_VALUE)
? return FALSE;
?// 設置位圖文件頭
?bmfHdr.bfType = 0x4D42; // "BM"
?dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;??
?bmfHdr.bfSize = dwDIBSize;
?bmfHdr.bfReserved1 = 0;
?bmfHdr.bfReserved2 = 0;
?bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;
?//? 寫入位圖文件頭
?WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
?//? 寫入位圖文件其余內(nèi)容
? WriteFile(fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize , &dwWritten, NULL);
?// 清除 ???
?GlobalUnlock(hDib);
?GlobalFree(hDib);
?CloseHandle(fh);
?return TRUE;
}
3.使用舉例 :
1> 截取保存當前運行程序的畫面
CRect rect;
GetWindowRect(&rect);
HBITMAP hMap = CopyScreenToBitmap(rect);
SaveBitmapToFile(hMap,"C:\\seu07201213( 汪洋中的一片葉子 ).bmp");
2> 全屏截圖
CRect rect;
rect.left = 0;
rect.top = 0;
rect.right = GetSystemMetrics(SM_CXSCREEN);
rect.bottom = GetSystemMetrics(SM_CYSCREEN);
HBITMAP hMap = CopyScreenToBitmap(rect);
SaveBitmapToFile(hMap,"C:\\seu07201213(汪洋中的一片葉子).bmp");
from:?http://blog.csdn.net/masibuaa/article/details/7659657
總結(jié)
以上是生活随笔為你收集整理的VC屏幕截图并保存为bmp文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MFC90条技巧-带目录
- 下一篇: 傅里叶变换在图像处理中的作用