您的位置:首页 > 其它

截取屏幕指定区域保存为BMP文件

2011-09-06 00:23 561 查看
void main()

{

HBITMAP hCaptureBitmap = CopyScreenToBitmap(215, 374, 774, 795);

SaveCapturedBitmap(hCaptureBitmap, "Hello.bmp");

}

HBITMAP CErefrefrfDlg::CopyScreenToBitmap(LPRECT lpRect)

{

HDC hSrcDC, hMemDC;

//位图句柄

HBITMAP hBitmap, hOldBitmap;

//选定区域坐标

int nX, nY, nX2, nY2;

//位图宽度和高度

int nWidth, nHeight;

//屏幕分辨率

int xScrn, yScrn;

//确保选定区域不为空矩形

if(IsRectEmpty(lpRect))

return NULL;

//为屏幕创建设备描述表

hSrcDC = CreateDC("DISPLAY", NULL, NULL, NULL);

//为屏幕设备描述表创建兼容的内存设备描述表

hMemDC = CreateCompatibleDC(hSrcDC);

//获得选定区域坐标

nX = lpRect->left;

nY = lpRect->top;

nX2 = lpRect->right;

nY2 = lpRect->bottom;

//获得屏幕分辨率

xScrn = GetDeviceCaps(hSrcDC, HORZRES);

yScrn = GetDeviceCaps(hSrcDC, VERTRES);

//确保选定区域是可见的

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;

//创建一个与屏幕设备描述表兼容的位图

hBitmap = CreateCompatibleBitmap(hSrcDC, nWidth, nHeight);

//把新位图选到内存设备描述表中

hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

//把屏幕设备描述表拷贝到内存设备描述表中

BitBlt(hMemDC, 0, 0, nWidth, nHeight, hSrcDC, nX, nY, SRCCOPY);

//得到屏幕位图的句柄

hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);

//清除

DeleteDC(hSrcDC);

DeleteDC(hMemDC);

}

HBITMAP CErefrefrfDlg::CopyScreenToBitmap(int x1, int x2, int y1, int y2)

{

HDC hSrcDC, hMemDC;

 //位图句柄

 HBITMAP hBitmap, hOldBitmap;

 //选定区域坐标

 int nX, nY, nX2, nY2;

 //位图宽度和高度

 int nWidth, nHeight;

 //屏幕分辨率

 int xScrn, yScrn;

/*

 //确保选定区域不为空矩形

 if(IsRectEmpty(lpRect))

  return NULL;*/

 //为屏幕创建设备描述表

 hSrcDC = CreateDC("DISPLAY", NULL, NULL, NULL);

 //为屏幕设备描述表创建兼容的内存设备描述表

 hMemDC = CreateCompatibleDC(hSrcDC);

 //获得选定区域坐标

 nX = x1;

 nY = y1;

 nX2 = x2;

 nY2 = y2;

 //获得屏幕分辨率

 xScrn = GetDeviceCaps(hSrcDC, HORZRES);

 yScrn = GetDeviceCaps(hSrcDC, VERTRES);

 //确保选定区域是可见的

 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;

 //创建一个与屏幕设备描述表兼容的位图

 hBitmap = CreateCompatibleBitmap(hSrcDC, nWidth, nHeight);

 //把新位图选到内存设备描述表中

 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

 //把屏幕设备描述表拷贝到内存设备描述表中

 BitBlt(hMemDC, 0, 0, nWidth, nHeight, hSrcDC, nX, nY, SRCCOPY);

 //得到屏幕位图的句柄

 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);

 //清除

 DeleteDC(hSrcDC);

 DeleteDC(hMemDC);

 //返回位置句柄

 return hBitmap;

}

BOOL SaveCapturedBitmap(HBITMAP hBitmap, CString FileName)

{

 if(hBitmap==NULL || FileName.IsEmpty())

 {

     AfxMessageBox("参数错误");

  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(FileName, 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null colors file bi