WINAPI 拷贝指定的hDC的lpRect部分到文件Dstfile中(BMP文件格式)

 

#include <stdio.h>
#include <tchar.h>

//WINAPI 拷贝指定的hDC的lpRect部分到文件Dstfile中(BMP文件格式)
BOOL SaveHDCToFile(HDC hDC, LPRECT lpRect, LPCTSTR Dstfile)
{
  int Width = lpRect->right - lpRect->left; 
  int Height = lpRect->bottom - lpRect->top;

  HDC memDC = CreateCompatibleDC(hDC);//内存DC 
  HBITMAP memBitmap = CreateCompatibleBitmap(hDC, Width, Height); //建立和屏幕兼容的bitmap  
  HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);//将memBitmap选入内存DC 
  BitBlt(memDC, 0, 0, Width, Height,
    hDC, lpRect->left, lpRect->top, 
    SRCCOPY);//复制屏幕图像到内存DC 

  //以下代码保存memDC中的位图到文件 
  BITMAP bmpInfo; 
  GetObject(memBitmap, sizeof(bmpInfo), &bmpInfo);//获得位图信息 

  DWORD bmpBytesSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;

  BITMAPFILEHEADER bfh = {0};//位图文件头 
  bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量 
  bfh.bfSize = bfh.bfOffBits +  bmpBytesSize ;//文件总的大小 
  bfh.bfType = (WORD)0x4d42; 

  BITMAPINFOHEADER bih = {0};//位图信息头 
  bih.biBitCount = bmpInfo.bmBitsPixel;//每个像素字节大小 
  bih.biCompression = BI_RGB; 
  bih.biHeight = bmpInfo.bmHeight;//高度 
  bih.biPlanes = 1; 
  bih.biSize = sizeof(BITMAPINFOHEADER); 
  bih.biSizeImage = bmpBytesSize;//图像数据大小 
  bih.biWidth = bmpInfo.bmWidth;//宽度  

  BYTE * p = new BYTE[bmpBytesSize];//申请内存保存位图数据  
  GetDIBits(memDC, memBitmap, 0, Height,
    p,(LPBITMAPINFO) &bih,  DIB_RGB_COLORS);//获取位图数据 

  //正常的还要对256及以下的颜色加颜色映射表,
  // 但是现在的显示模式基本上都是真彩(24或32位)显示,因此忽略此项

 //保存到文件
  HANDLE hFile = CreateFile(Dstfile,
    GENERIC_WRITE,
    0, NULL, 
    CREATE_ALWAYS,
    0,
    NULL);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    DWORD dwBytesWritten;

    WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);//写入位图文件头 
    WriteFile(hFile, &bih, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);//写入位图信息头 
    WriteFile(hFile, p, bmpInfo.bmWidthBytes * bmpInfo.bmHeight, &dwBytesWritten, NULL);//写入位图数据 
    CloseHandle(hFile);
  }
  else
  {
    TCHAR szMsg[256];
    _stprintf_s(szMsg, _T("CreateFile error=%lu"), GetLastError());
    MessageBox(NULL, szMsg, _T("Error"), MB_OK);
  }


  //结束清理工作
  delete [] p; 

  SelectObject(memDC, hOldBitmap);
  DeleteObject(memBitmap);
  DeleteDC(memDC);

  return(true);
}

 

//测试用例,按下任意键时保存成为位图
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
    case WM_PAINT: //绘图代码
    {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hWnd, &ps);
      TextOut(hdc, 0, 0, _T("ABCD"), 4);
      EndPaint(hWnd, &ps);
      break;
    }
    case WM_KEYDOWN: //按下一个按键的时候保存成位图文件
    {
      LPCTSTR szFileName = _T("C:\\test.bmp");
      HDC hDC = GetDC(hWnd);
      RECT rcRect;
      GetClientRect(hWnd, &rcRect);
      SaveHDCToFile(hDC, &rcRect, szFileName);
      ReleaseDC(hWnd, hDC);
      
      //ShellExecute(NULL, _T("open"), szFileName, NULL, NULL, SW_SHOWNORMAL);//打开图片查看
      break;
    }
    case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
    default:
    {
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  }
  return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值