保存dc内容为bmp文件 ,屏幕截图也可以(zt)

HBITMAP CopyScreenToBitmap(LPRECT lpRect)

//lpRect 代表选定区域

{

 HDC       hScrDC, hMemDC;     

 // 屏幕和内存设备描述表

 HBITMAP    hBitmap, hOldBitmap;  

 // 位图句柄

 int       nX, nY, nX2, nY2;     

 // 选定区域坐标

 int       nWidth, nHeight;     

 // 位图宽度和高度

 int       xScrn, yScrn;        

 // 屏幕分辨率

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

 if (IsRectEmpty(lpRect))

  return NULL;

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

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

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

 hMemDC = CreateCompatibleDC(hScrDC);

 // 获得选定区域坐标

 nX = lpRect->left;

 nY = lpRect->top;

 nX2 = lpRect->right;

 nY2 = lpRect->bottom;

 // 获得屏幕分辨率

 xScrn = GetDeviceCaps(hScrDC, HORZRES);

 yScrn = GetDeviceCaps(hScrDC, 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

  (hScrDC, nWidth, nHeight);

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

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

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

 BitBlt(hMemDC, 0, 0, nWidth, nHeight,

  hScrDC, nX, nY, SRCCOPY);

 //得到屏幕位图的句柄

 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);//这个时候可以把得到的句柄交给savebitmaptofile保存到文件,我在这里继续偷懒写

 //清除
 BITMAPINFOHEADER bih;
 bih.biSize =sizeof(BITMAPINFOHEADER);
 bih.biWidth =800;
 bih.biHeight = 600;
 bih.biPlanes = 1;
 bih.biBitCount= 8;//8bit bitmap
 bih.biCompression = BI_RGB;
 bih.biSizeImage = 0;
 bih.biXPelsPerMeter =0;
 bih.biYPelsPerMeter = 0;
 bih.biClrUsed = 0;
 bih.biClrImportant = 0;
 DWORD dwBmBitsSize=800*600*8/8;
 HANDLE hDib=GlobalAlloc(GHND,dwBmBitsSize+256*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER));//分配内存,GlobalAlloc分配内存能够和dll程序共享分配的内存(可以由非c++编译的dll释放),malloc的话只能有c++自己知道怎么释放

//分配的内容包括 BITMAPINFOHEADER + PALETTE(调色板) + 位图内容
 LPVOID ptr=(LPVOID)GlobalLock(hDib);
 *(BITMAPINFOHEADER*)ptr=bih;//保存那个BITMAPINFOHEADER到我们分配的内存
 HDC xdc=GetDC(NULL);
 //HPALETTE hPal= (HPALETTE)GetStockObject(DEFAULT_PALETTE);
 //HPALETTE hOldPal=(HPALETTE)SelectPalette(xdc,hPal,FALSE);
 //RealizePalette(xdc);
 if(!GetDIBits(hScrDC,hBitmap,0,600,
  (LPSTR)ptr+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD),
  (BITMAPINFO *)ptr,
  DIB_RGB_COLORS))

//参数说明 从哪个dc(一定要有正确的PALETTE) ,位图句柄,从哪一行(scanline),保存多少行,保存位图内容的地方,一个保存BITMAPINFO结构(GetDIBits会帮我们完善该死的PALETTE),颜色的表示方式,要得到bmp就一定要DIB_RGB_COLORS


 {
  return hBitmap;//如果GetDIBits 返回0那就失败了……
 }
 HANDLE fh = CreateFile("c://b.bmp", GENERIC_WRITE,

  0, NULL, CREATE_ALWAYS,

  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  NULL);

 if (fh == INVALID_HANDLE_VALUE)

  return FALSE;

 // 设置位图文件头
 BITMAPFILEHEADER bmfHdr;
 bmfHdr.bfType = 0x4D42;  // "BM"

 DWORD dwDIBSize    = sizeof(BITMAPFILEHEADER)

  + sizeof(BITMAPINFOHEADER)

  + 256*sizeof(RGBQUAD) + dwBmBitsSize; 

 bmfHdr.bfSize = dwDIBSize;

 bmfHdr.bfReserved1 = 0;

 bmfHdr.bfReserved2 = 0;

 bmfHdr.bfOffBits = (DWORD)sizeof

  (BITMAPFILEHEADER)

  + (DWORD)sizeof(BITMAPINFOHEADER)

  + 256*sizeof(RGBQUAD);

 // 写入位图文件头
 DWORD dwWritten;
 WriteFile(fh, (LPSTR)&bmfHdr, sizeof

  (BITMAPFILEHEADER), &dwWritten, NULL);

 // 写入位图文件其余内容

 WriteFile(fh, (LPSTR)ptr, dwDIBSize,

  &dwWritten, NULL);

 DeleteDC(hScrDC);

 DeleteDC(hMemDC);

 // 返回位图句柄

 return hBitmap;

}

int SaveBitmapToFile(HBITMAP hBitmap ,

      LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄

{      //lpFileName 为位图文件名

 HDC            hDC;        

 //设备描述表

 int            iBits;     

 //当前显示分辨率下每个像素所占字节数

 WORD            wBitCount;  

 //位图中每个像素所占字节数

 //定义调色板大小, 位图中像素字节大小 ,

 //位图文件大小 , 写入文件字节数

 DWORD           dwPaletteSize=0,

  dwBmBitsSize,

  dwDIBSize, dwWritten;

 BITMAP          Bitmap;       

 //位图属性结构

 BITMAPFILEHEADER   bmfHdr;       

 //位图文件头结构

 BITMAPINFOHEADER   bi;           

 //位图信息头结构

 LPBITMAPINFOHEADER lpbi;         

 //指向位图信息头结构

 HANDLE          fh, hDib;
 HPALETTE 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;

 //计算调色板大小
 wBitCount=8;
 if (wBitCount <= 8)

  dwPaletteSize = (1 <<  wBitCount) *

  sizeof(RGBQUAD);

 //设置位图信息头结构

 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 ;

 //为位图内容分配内存

 hDib  = GlobalAlloc(GHND,dwBmBitsSize+

  dwPaletteSize+sizeof(BITMAPINFOHEADER));

 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);

 *lpbi = bi;

 // 处理调色板  

 hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);

 if (hPal)

 {

  hDC  = GetDC(NULL);

  hOldPal = SelectPalette(hDC, 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, hOldPal, TRUE);

  RealizePalette(hDC);

  ReleaseDC(NULL, hDC);

 }

 //创建位图文件   

 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);

 // 写入位图文件其余内容

 WriteFile(fh, (LPSTR)lpbi, dwDIBSize,

  &dwWritten, NULL);

 //清除  

 GlobalUnlock(hDib);

 GlobalFree(hDib);

 CloseHandle(fh);

}

//我也是半懂不懂的状态..

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值