找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 8475|回复: 1

[例程] 【分享】截取屏幕指定区域保存为BMP文件

[复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2009-9-6 16:53:17 | 显示全部楼层 |阅读模式
  1. HBITMAP CopyScreenToBitmap(LPRECT lpRect)
  2. {
  3. //屏幕和内存设备描述表
  4. HDC hSrcDC, hMemDC;
  5. //位图句柄
  6. HBITMAP hBitmap, hOldBitmap;
  7. //选定区域坐标
  8. int nX, nY, nX2, nY2;
  9. //位图宽度和高度
  10. int nWidth, nHeight;
  11. //屏幕分辨率
  12. int xScrn, yScrn;
  13. //确保选定区域不为空矩形
  14. if(IsRectEmpty(lpRect))
  15.    return NULL;
  16. //为屏幕创建设备描述表
  17. hSrcDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  18. //为屏幕设备描述表创建兼容的内存设备描述表
  19. hMemDC = CreateCompatibleDC(hSrcDC);
  20. //获得选定区域坐标
  21. nX = lpRect->left;
  22. nY = lpRect->top;
  23. nX2 = lpRect->right;
  24. nY2 = lpRect->bottom;
  25. //获得屏幕分辨率
  26. xScrn = GetDeviceCaps(hSrcDC, HORZRES);
  27. yScrn = GetDeviceCaps(hSrcDC, VERTRES);
  28. //确保选定区域是可见的
  29. if(nX<0)
  30.    nX = 0;
  31. if(nY<0)
  32.    nY = 0;
  33. if(nX2>xScrn)
  34.    nX2 = xScrn;
  35. if(nY2>yScrn)
  36.    nY2 = yScrn;
  37. nWidth = nX2 - nX;
  38. nHeight = nY2 - nY;
  39. //创建一个与屏幕设备描述表兼容的位图
  40. hBitmap = CreateCompatibleBitmap(hSrcDC, nWidth, nHeight);
  41. //把新位图选到内存设备描述表中
  42. hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
  43. //把屏幕设备描述表拷贝到内存设备描述表中
  44. BitBlt(hMemDC, 0, 0, nWidth, nHeight, hSrcDC, nX, nY, SRCCOPY);
  45. //得到屏幕位图的句柄
  46. hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
  47. //清除
  48. DeleteDC(hSrcDC);
  49. DeleteDC(hMemDC);
  50. //返回位置句柄
  51. }
  52. */
  53. HBITMAP CopyScreenToBitmap(int x1, int x2, int y1, int y2)
  54. {
  55. //屏幕和内存设备描述表
  56. HDC hSrcDC, hMemDC;
  57. //位图句柄
  58. HBITMAP hBitmap, hOldBitmap;
  59. //选定区域坐标
  60. int nX, nY, nX2, nY2;
  61. //位图宽度和高度
  62. int nWidth, nHeight;
  63. //屏幕分辨率
  64. int xScrn, yScrn;
  65. /*
  66. //确保选定区域不为空矩形
  67. if(IsRectEmpty(lpRect))
  68.    return NULL;*/
  69. //为屏幕创建设备描述表
  70. hSrcDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  71. //为屏幕设备描述表创建兼容的内存设备描述表
  72. hMemDC = CreateCompatibleDC(hSrcDC);
  73. //获得选定区域坐标
  74. nX = x1;
  75. nY = y1;
  76. nX2 = x2;
  77. nY2 = y2;
  78. //获得屏幕分辨率
  79. xScrn = GetDeviceCaps(hSrcDC, HORZRES);
  80. yScrn = GetDeviceCaps(hSrcDC, VERTRES);
  81. //确保选定区域是可见的
  82. if(nX<0)
  83.    nX = 0;
  84. if(nY<0)
  85.    nY = 0;
  86. if(nX2>xScrn)
  87.    nX2 = xScrn;
  88. if(nY2>yScrn)
  89.    nY2 = yScrn;
  90. nWidth = nX2 - nX;
  91. nHeight = nY2 - nY;
  92. //创建一个与屏幕设备描述表兼容的位图
  93. hBitmap = CreateCompatibleBitmap(hSrcDC, nWidth, nHeight);
  94. //把新位图选到内存设备描述表中
  95. hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
  96. //把屏幕设备描述表拷贝到内存设备描述表中
  97. BitBlt(hMemDC, 0, 0, nWidth, nHeight, hSrcDC, nX, nY, SRCCOPY);
  98. //得到屏幕位图的句柄
  99. hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
  100. //清除
  101. DeleteDC(hSrcDC);
  102. DeleteDC(hMemDC);
  103. //返回位置句柄
  104. return hBitmap;
  105. }
  106. BOOL SaveCapturedBitmap(HBITMAP hBitmap, CString FileName)
  107. {
  108. if(hBitmap==NULL || FileName.IsEmpty())
  109. {
  110.      AfxMessageBox("参数错误");
  111.    return false;
  112. }
  113. HDC hDC;
  114. //当前分辨率下每象素所占字节数
  115. int iBits;
  116. //位图中每象素所占字节数
  117. WORD wBitCount;
  118. //定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
  119. DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;
  120. //位图属性结构
  121. BITMAP Bitmap;
  122. //位图文件头结构
  123. BITMAPFILEHEADER bmfHdr;
  124. //位图信息头结构
  125. BITMAPINFOHEADER bi;
  126. //指向位图信息头结构
  127. LPBITMAPINFOHEADER lpbi;
  128. //定义文件,分配内存句柄,调色板句柄
  129. HANDLE fh, hDib, hPal,hOldPal=NULL;

  130. //计算位图文件每个像素所占字节数
  131. hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  132. iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
  133. DeleteDC(hDC);
  134. if (iBits <= 1) wBitCount = 1;
  135. else if (iBits <= 4) wBitCount = 4;
  136. else if (iBits <= 8) wBitCount = 8;
  137. else      wBitCount = 24;

  138. GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
  139. bi.biSize   = sizeof(BITMAPINFOHEADER);
  140. bi.biWidth   = Bitmap.bmWidth;
  141. bi.biHeight   = Bitmap.bmHeight;
  142. bi.biPlanes   = 1;
  143. bi.biBitCount = wBitCount;
  144. bi.biCompression = BI_RGB;
  145. bi.biSizeImage = 0;
  146. bi.biXPelsPerMeter = 0;
  147. bi.biYPelsPerMeter = 0;
  148. bi.biClrImportant = 0;
  149. bi.biClrUsed = 0;

  150. dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

  151. //为位图内容分配内存
  152. hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
  153. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  154. *lpbi = bi;
  155. // 处理调色板
  156. hPal = GetStockObject(DEFAULT_PALETTE);
  157. if (hPal)
  158. {
  159.    hDC = ::GetDC(NULL);
  160.    hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);
  161.    RealizePalette(hDC);
  162. }
  163. // 获取该调色板下新的像素值
  164. GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
  165.     +dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);

  166. //恢复调色板
  167. if (hOldPal)
  168. {
  169.    ::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
  170.    RealizePalette(hDC);
  171.    ::ReleaseDC(NULL, hDC);
  172. }
  173. //创建位图文件
  174. fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
  175.    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

  176. if (fh == INVALID_HANDLE_VALUE) return FALSE;

  177. // 设置位图文件头
  178. bmfHdr.bfType = 0x4D42; // "BM"
  179. dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
  180. bmfHdr.bfSize = dwDIBSize;
  181. bmfHdr.bfReserved1 = 0;
  182. bmfHdr.bfReserved2 = 0;
  183. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
  184. // 写入位图文件头
  185. WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
  186. // 写入位图文件其余内容
  187. WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
  188. //清除
  189. GlobalUnlock(hDib);
  190. GlobalFree(hDib);
  191. CloseHandle(fh);
  192. return TRUE;
  193. }
  194. int main()
  195. {
  196. HBITMAP hCaptureBitmap = CopyScreenToBitmap(100, 700, 100, 700);
  197. SaveCapturedBitmap(hCaptureBitmap, "Hello.bmp");
  198. return 0;
  199. }
复制代码
REF:http://weiyuweizhi.blog.163.com/ ... 332120091493344277/
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755

2

主题

17

回帖

0

精华

铜牌会员

积分
35
发表于 2010-9-23 15:44:54 | 显示全部楼层
:loveliness:
学习~!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表