抓图函数
//抓圖函數
void CWallPaperDlg::PrintScreenToFile(char filename[])
{
?//獲取當前整個屏幕DC
?HDC hDC = ::GetDC(NULL);
?//獲得顏色模式
?int BitPerPixel = GetDeviceCaps(hDC, BITSPIXEL);
?int Width = GetDeviceCaps(hDC, HORZRES);
?int Height = GetDeviceCaps(hDC, VERTRES);
?
?//創建與獲得的CDC兼容的內存設備描述
?HDC hMemDC = CreateCompatibleDC(hDC);
?
?//建立和屏幕兼容的bitmap
?HBITMAP hMemBitmap, hOldMemBitmap;
?
?//初始化memBitmap
?hMemBitmap = CreateCompatibleBitmap(hDC, Width, Height);
?
?//將memBitmap選入內存DC
?hOldMemBitmap = (HBITMAP)SelectObject(hMemDC, hMemBitmap);
?
?//復制屏幕圖像到內存DC
?BitBlt(hMemDC,0, 0, Width, Height, hDC, 0, 0, SRCCOPY);
?
?//以下代碼保存hMemDC中的位圖到文件
?BITMAP bmp;
?//獲得位圖信息
?GetObject( hMemBitmap, (int)sizeof(BITMAP), &bmp );
?
?FILE *fp = fopen(filename, "w+b");
?
?//位圖信息頭
?BITMAPINFOHEADER bih = {0};
?//每個像素字節大小
?bih.biBitCount = bmp.bmBitsPixel;
?//無壓縮
?bih.biCompression = BI_RGB;
?//高度
?bih.biHeight = bmp.bmHeight;
?bih.biPlanes = 1;
?bih.biSize = sizeof(BITMAPINFOHEADER);
?
?//圖像數據大小
?bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;
?
?//寬度
?bih.biWidth = bmp.bmWidth;
?
?//位圖文件頭
?BITMAPFILEHEADER bfh = {0};
?
?//到位圖數據的偏移量
?bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
?
?//文件總的大小
?bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;
?
?//字符"BM",表示位圖文件
?bfh.bfType = (WORD)0x4d42;
?
?//寫入位圖文件頭
?fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
?//寫入位圖信息頭
?fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
?//申請內存保存位圖數據
?BYTE * p = new BYTE[bmp.bmWidthBytes * bmp.bmHeight];
?//獲取位圖數據
?GetDIBits(hMemDC, hMemBitmap, 0, Height, p, (LPBITMAPINFO) &bih, DIB_RGB_COLORS);
??
?//寫入位圖數據
?fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);
?
?delete [] p;
?fclose(fp);
?SelectObject(hMemDC, hOldMemBitmap);
}
?
?
---------------------------------------------------------------------------------------------------
static HBITMAP CopyDCToBitmap(HDC hDC, LPRECT lpRect)
{
if(!hDC || !lpRect || IsRectEmpty(lpRect))
?? return NULL;
HDC hMemDC; // 內存設備描述表
HBITMAP hBitmap, hOldBitmap; // 位圖句柄
int nX, nY, nX2, nY2; // 選定區域坐標
int nWidth, nHeight;?? // 位圖寬度和高度
// 獲得選定區域坐標
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 為指定設備描述表創建兼容的內存設備描述表
hMemDC = CreateCompatibleDC(hDC);
// 創建一個與指定設備描述表兼容的位圖
hBitmap = CreateCompatibleBitmap(hDC, nWidth, nHeight);
// 把新位圖選到內存設備描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把指定的設備描述表拷貝到內存設備描述表中
StretchBlt(hMemDC, 0, 0, nWidth, nHeight, hDC, nX, nY, nWidth, nHeight, SRCCOPY);
// 得到內存位圖的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
// 清除
DeleteDC(hMemDC);
DeleteObject(hOldBitmap);
// 返回位圖句柄
return hBitmap;
}
// 把HBITMAP保存成位圖
static BOOL SaveBmp(HBITMAP hBitmap, const char *pchFileName)
{
if(!hBitmap || !pchFileName)
?? return FALSE;
HDC hDC;
int iBits; // 當前分辨率下每象素所占字節數
WORD wBitCount; // 位圖中每象素所占字節數
// 定義調色板大小, 位圖中像素字節大小 ,位圖文件大小 , 寫入文件字節數
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
BITMAP Bitmap;?? // 位圖屬性結構
BITMAPFILEHEADER bmfHdr;?? // 位圖文件頭結構
BITMAPINFOHEADER bi;?? // 位圖信息頭結構
LPBITMAPINFOHEADER lpbi;?? // 指向位圖信息頭結構
HANDLE fh, hDib, hPal, hOldPal = NULL; // 定義文件,分配內存句柄,調色板句柄
// 計算位圖文件每個像素所占字節數
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
?? wBitCount = 24;
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.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
//為位圖內容分配內存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 處理調色板??
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal) {
?? hDC = ::GetDC(NULL);
?? hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
?? RealizePalette(hDC);
}
// 獲取該調色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
?? (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,
?? (BITMAPINFO *)lpbi, DIB_RGB_COLORS);
// 恢復調色板??
if(hOldPal) {
?? ::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
?? RealizePalette(hDC);
?? ::ReleaseDC(NULL, hDC);
}
// 創建位圖文件
fh = CreateFile(pchFileName, 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);
// 寫入位圖文件其余內容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
// 清除??
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
// 抓圖
if (m_bRealPlay || m_bPlayBack) {
?? CRect rect, barRect;
?? HDC hDC = GetDC()->m_hDC;
?? GetClientRect(&rect);
?? if (m_bPlayBack) {
??? m_bar.GetWindowRect(&barRect);
??? rect.bottom = rect.bottom - barRect.Height();
?? }
?? HBITMAP bmp = CopyDCToBitmap(hDC, &rect);
?? if (!SaveBmp(bmp, "D://a.bmp"))
??? ::AfxMessageBox("save the file /"a.bmp/" failed.");
}
?
總結
- 上一篇: ListView图片不显示 Applic
- 下一篇: vs2005制作安装包(自动安装.net