广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现屏幕截图(全屏截图)
  • 114
分享到

C++实现屏幕截图(全屏截图)

2024-04-02 19:04:59 114人浏览 独家记忆
摘要

上回分享了一个全屏截图的代码,保存为BMP, c++实现屏幕截图(全屏截图):https://www.jb51.net/article/140184.htm 实际使用的过程中我发现截

上回分享了一个全屏截图的代码,保存为BMP,

c++实现屏幕截图(全屏截图):https://www.jb51.net/article/140184.htm

实际使用的过程中我发现截图文件实在大,无赖又整成了PNG截图,现在分享出来。

MakePNG.h


//MakePNG.h
 
#pragma once
#include <GdiPlus.h>
using namespace Gdiplus;
#pragma comment(lib,"GdiPlus.lib") 
 
class CMakePNG
{
public:
 CMakePNG(void);
 ~CMakePNG(void);
 
 BOOL MakePNG(HDC hDC,CRect rect,CString strFilePath);
 BOOL BMptoPNG(LPCWSTR StrBMp,LPCWSTR StrPNG);
 BOOL PNGtoBMp(LPCWSTR StrPNG,LPCWSTR StrBMp);
 BOOL GetEncoderClsid(WCHAR* pFORMat,CLSID* pClsid);
private:
 GdiplusStartupInput m_gdiplusStartupInput;
 ULONG_PTR m_pGdiToken;
};

MakePNG.cpp


//MakePNG.cpp
 
#include "StdAfx.h"
#include "MakePNG.h"
 
CMakePNG::CMakePNG(void)
{
 GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);
}
 
CMakePNG::~CMakePNG(void)
{
}
 






BOOL CMakePNG::MakePNG(HDC hDC, CRect rect, CString strFilePath)
{
 BITMAP bmp;
 PBITMapiNFO pbmi; 
 PBITMAPINFOHEADER pbih;     // bitmap info-header 
 BITMAPFILEHEADER  hdr;      // bitmap file-header
 Word    cClrBits; 
 LPBYTE lpBits;              // memory pointer
 DWORD dwTmp; 
 DWORD cb;                   // incremental count of bytes 
 BYTE *hp;                   // byte pointer 
 HANDLE hfile;               // file handle 
 CString szBMPFilename = strFilePath.Left(strFilePath.GetLength() - 3) + _T("bmp");//先保存成位图
 HDC hdcCompatible = CreateCompatibleDC(hDC);
 HBITMAP hbmScreen = CreateCompatibleBitmap(hDC, rect.Width(), rect.Height());
 
 if (hbmScreen == NULL)
 {
     AfxMessageBox(_T("CreateCompatibleBitmap() error")); 
  return FALSE;
 }
 
 // Select the bitmaps into the compatible DC. 
 
 if (!SelectObject(hdcCompatible, hbmScreen)) 
 {
  AfxMessageBox(_T("Compatible Bitmap Selection error")); 
  return FALSE;
 }
 
 //Copy color data for the entire display into a 
 //bitmap that is selected into a compatible DC. 
 
 if (!BitBlt(hdcCompatible, 
  0,0, 
  rect.Width(), rect.Height(), 
  hDC, 
  rect.left,rect.top, 
  SRCCOPY)) 
 {
        AfxMessageBox(_T("Screen to Compat Blt Failed"));
  return FALSE;
 }
 
 
 
 // Retrieve the bitmap's color format, width, and height. 
 if (!GetObject(hbmScreen, sizeof(BITMAP), (LPSTR)&bmp))
 {
        AfxMessageBox(_T("GetObject()出错!"));
  return FALSE;
 }
 // Convert the color format to a count of bits. 
 cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); 
 if (cClrBits == 1) 
  cClrBits = 1; 
 else if (cClrBits <= 4) 
  cClrBits = 4; 
 else if (cClrBits <= 8) 
  cClrBits = 8; 
 else if (cClrBits <= 16) 
  cClrBits = 16; 
 else if (cClrBits <= 24) 
  cClrBits = 24; 
 else cClrBits = 32; 
 
 // Allocate memory for the BITMAPINFO structure. (This structure 
 // contains a BITMAPINFOHEADER structure and an array of RGBQUAD 
 // data structures.) 
 
 if (cClrBits != 24) 
  pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
  sizeof(BITMAPINFOHEADER) + 
  sizeof(RGBQUAD) * (1<< cClrBits)); 
 
 // There is no RGBQUAD array for the 24-bit-per-pixel format. 
 
 else 
  pbmi = (PBITMAPINFO) LocalAlloc(LPTR, 
  sizeof(BITMAPINFOHEADER)); 
 
 // Initialize the fields in the BITMAPINFO structure. 
 
 pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
 pbmi->bmiHeader.biWidth = bmp.bmWidth; 
 pbmi->bmiHeader.biHeight = bmp.bmHeight; 
 pbmi->bmiHeader.biPlanes = bmp.bmPlanes; 
 pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; 
 if (cClrBits < 24) 
  pbmi->bmiHeader.biClrUsed = (1<<cClrBits); 
 
 // If the bitmap is not compressed, set the BI_RGB flag. 
 pbmi->bmiHeader.biCompression = BI_RGB; 
 
 // Compute the number of bytes in the array of color 
 // indices and store the result in biSizeImage. 
 pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
  * pbmi->bmiHeader.biHeight; 
 // Set biClrImportant to 0, indicating that all of the device colors are important. 
 pbmi->bmiHeader.biClrImportant = 0; 
 
 pbih = (PBITMAPINFOHEADER) pbmi; 
 lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
 
 if (!lpBits) 
 {
     AfxMessageBox(_T("内存分配错误!"));
  return FALSE;
 }
 // Retrieve the color table (RGBQUAD array) and the bits 
 // (array of palette indices) from the DIB. 
 if (!GetDIBits(hDC, hbmScreen, 0, (WORD) pbih->biHeight, lpBits, pbmi, 
  DIB_RGB_COLORS)) 
 {
  AfxMessageBox(_T("GetDIBits() error"));
  return FALSE;
 }
 
 // Create the .BMP file. 
 hfile = CreateFile(szBMPFilename, 
  GENERIC_READ | GENERIC_WRITE, 
  (DWORD) 0, 
  NULL, 
  CREATE_ALWAYS, 
  FILE_ATTRIBUTE_NORMAL, 
  (HANDLE) NULL); 
 if (hfile == INVALID_HANDLE_VALUE) 
 {
   AfxMessageBox(_T("创建文件失败"));
  return false;
 }
 hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M" 
 // Compute the size of the entire file. 
 hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + 
  pbih->biSize + pbih->biClrUsed 
  * sizeof(RGBQUAD) + pbih->biSizeImage); 
 hdr.bfReserved1 = 0; 
 hdr.bfReserved2 = 0; 
 
 // Compute the offset to the array of color indices. 
 hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + 
  pbih->biSize + pbih->biClrUsed 
  * sizeof (RGBQUAD); 
 
 // Copy the BITMAPFILEHEADER into the .BMP file. 
 if (!WriteFile(hfile, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), 
  (LPDWORD) &dwTmp,  NULL)) 
 {
   AfxMessageBox(_T("写BMP文件头失败"));
  return FALSE;
 }
 
 // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. 
 if (!WriteFile(hfile, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) 
  + pbih->biClrUsed * sizeof (RGBQUAD), 
  (LPDWORD) &dwTmp, ( NULL))) 
 {
   AfxMessageBox(_T("写BMP文件头失败"));
  return FALSE;
 }
 
 // Copy the array of color indices into the .BMP file. 
 cb = pbih->biSizeImage; 
 hp = lpBits; 
 if (!WriteFile(hfile, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) 
 {
  AfxMessageBox(_T("写入BMP文件失败"));
  return FALSE;
 }
 
 // Close the .BMP file. 
 if (!CloseHandle(hfile)) 
 {
   AfxMessageBox(_T("Can't close BMP file.")); 
 }
 
  // Free memory. 
  GlobalFree((HGLOBAL)lpBits);
 
 //转换成PNG
 if(!BMptoPNG(szBMPFilename,strFilePath))
 {
  DeleteFile(szBMPFilename);
  return FALSE;
 }
 DeleteObject(hbmScreen);
 DeleteFile(szBMPFilename);
 return TRUE;
}
// //转换BMP文件为PNG文件            
BOOL CMakePNG::BMptoPNG(LPCWSTR StrBMp,LPCWSTR StrPNG)
{
 CLSID encoderClsid;
 Status stat;
 Image* image = NULL;
 image = Bitmap::FromFile(StrBMp,TRUE);
 if (!GetEncoderClsid(L"image/png",&encoderClsid))
 {
  return FALSE;
 }
 stat = image->Save(StrPNG,&encoderClsid,NULL);
 if (stat != Ok)
 {
  return FALSE;
 }
 delete image;
 return TRUE;
}
 
// 功能描述:  转换PNG文件为BMP文件      
BOOL CMakePNG::PNGtoBMp(LPCWSTR StrPNG,LPCWSTR StrBMp)
{
 CLSID encoderClsid;
 Status stat;
 Image* pImage;
 pImage = Bitmap::FromFile(StrPNG,TRUE);
 if (!GetEncoderClsid(L"image/bmp",&encoderClsid))
 {
  return FALSE;
 }
 stat = pImage->Save(StrBMp,&encoderClsid,NULL);
 if (stat != Ok)
 {
  return FALSE;
 }
 delete pImage;
 return TRUE;
}
 
BOOL CMakePNG::GetEncoderClsid(WCHAR* pFormat,CLSID* pClsid)
{
 UINT num = 0,size = 0;
 ImageCodecInfo* pImageCodecInfo = NULL;
 GetImageEncodersSize(&num,&size);
 if (size == 0)
 {
  return FALSE;
 }
 pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
 if (pImageCodecInfo == NULL)
 {
  return FALSE;
 }
 GetImageEncoders(num,size,pImageCodecInfo);
 BOOL bfound = FALSE;
 for (UINT i = 0;!bfound && i < num;  i++)
 {
  if (_wcsicmp(pImageCodecInfo[i].MimeType,pFormat) == 0)
  {
   *pClsid = pImageCodecInfo[i].Clsid;
   bfound = TRUE;
  }
 }
 free(pImageCodecInfo);
 return bfound;
}

以上两个文件实际上是CMakePNG类,使用时需要把他们添加到项目中,调用方法如下:


wstring GetAppPathW()
{
 wchar_t szExePath[MAX_PATH] = {0};
 GetModuleFileNameW(NULL, szExePath, MAX_PATH);
 wchar_t *pstr = wcsrchr(szExePath, '\\');
 memset(pstr + 1, 0, 2);
 wstring strAppPath(szExePath);
 return strAppPath;
}
 
// 屏幕截图
CString CDemoDlg::ScreenShot(void)
{
 CWnd *pDesktop = GetDesktopWindow();  
 CDC *pDC = pDesktop->GetDC();  
 CRect rect;  
 //获取窗口的大小  
 pDesktop->GetClientRect(&rect);
 
 //保存到的文件名
 CString strFileName(GetAppPathW().c_str());
 strFileName += _T("ScreenShot\\");
 CreateDirectory((LPCTSTR)strFileName,NULL);
 CTime t = CTime::GetCurrentTime();
 CString tt = t.Format("%Y%m%d_%H%M%S");
 strFileName += tt;
 strFileName += _T(".PNG");
 //保存为PNG
 CMakePNG MakePNG;
 MakePNG.MakePNG(pDC->m_hDC,rect,strFileName);
 ReleaseDC(pDC);
 return strFileName;
}

到此这篇关于C++实现屏幕截图(全屏截图)的文章就介绍到这了,更多相关C++ 屏幕截图内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++实现屏幕截图(全屏截图)

本文链接: https://www.lsjlt.com/news/156921.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++实现屏幕截图(全屏截图)
    上回分享了一个全屏截图的代码,保存为BMP, C++实现屏幕截图(全屏截图):https://www.jb51.net/article/140184.htm 实际使用的过程中我发现截...
    99+
    2022-11-12
  • Android 截屏实现、屏幕截图、MediaProjection、ImageReader
    1. 第一步:调起系统捕获屏幕的Intent MainActivity:public void goCaptureIntent() { //第一步.调起系统捕获屏幕的Intent mMediaProjectionManager ...
    99+
    2023-10-08
    android 图像处理 service_mash android-studio android studio
  • python实现屏幕截图
    由于在我的一个程序中想要添加一个截图功能,今天看一下利用Python怎样截图,功能实现都挺简单了,直接上代码 from PIL import ImageGrab im = ImageGrab.grab() im.save(addr,'jp...
    99+
    2023-01-31
    截图 屏幕 python
  • C++如何实现截图截屏
    这篇文章主要介绍了C++如何实现截图截屏,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、截图工具1.1 键盘截图(PrtScn键)如何使用Microsoft Windows...
    99+
    2023-06-21
  • win7如何屏幕截图
    你是不是还在用QQ进行电脑屏幕截图呢为了截图还要打开电脑QQ实在是有点麻烦,你想知道win7如何屏幕截图吗那就快跟小编一起来看看用win7系统如何进行截图吧.方法一:截图快捷键按下键盘上的“PrtSc”或者位于键盘右上方的“PrtSc”截图...
    99+
    2023-07-19
  • 怎么用Python实现屏幕截图
    本文小编为大家详细介绍“怎么用Python实现屏幕截图”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Python实现屏幕截图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、序言在csdn上有很多纯cop...
    99+
    2023-06-28
  • Python 实现Mac 屏幕截图详解
    目录前言pyscreenshotgithub地址Python 安装用例代码截图效果总结前言 最近想做个小玩意,需要在mac端实现屏幕截图,搜了下网上中文资源都比较老旧,于是查了下,发...
    99+
    2022-11-12
  • 用Python实现屏幕截图详解
    目录一、序言二、环境配置三、屏幕截屏源码与解析四、结语一、序言 在csdn上有很多纯copy,这给我复现带来了很大的麻烦,所以我想根据我的个人找截图的经历记录下来,给未来的自己看,免...
    99+
    2022-11-13
  • C#实现循环发送电脑屏幕截图
    本文实例为大家分享了C#实现循环发送电脑屏幕截图的具体代码,供大家参考,具体内容如下 写的一个demo,建立Socket连接之后,循环发送电脑屏幕截图 服务器端开启之后监听端口号20...
    99+
    2022-11-12
  • C++实现截图截屏的示例代码
    目录1、截图工具1.1 键盘截图(PrtScn键)1.2 win10自带截图(Win+Shift+S)1.3 系统自带的截图小工具1.4 ffmpeg1.5 ScreenToGif1...
    99+
    2022-11-12
  • 原生JS实现简单屏幕截图
    目录了解 HTML5 中的 Canvas获取屏幕截图结论在 Web 开发中,截图是一项非常有用的技术。可以使用截图来记录当前屏幕状态,生成缩略图或进行屏幕分享等操作。在本文中,我将介...
    99+
    2023-05-15
    JS 屏幕截图 JS 原生截图
  • go语言怎么实现屏幕截图
    今天小编给大家分享一下go语言怎么实现屏幕截图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。借助第三方库安装go ...
    99+
    2023-06-30
  • Win8系统自动保存全屏截图将整个屏幕截图并自动保存
    在Win8系统里,当按下PrtSc键时,会将当前整个屏幕内容以图画的形式暂时存放到剪贴板中,按下Alt+PrtSc键则是将活动窗口以图画的形式暂时存放到剪贴板中。在Win8中,除了以上两组快捷键外,我们又多...
    99+
    2022-06-04
    截图 自动保存 全屏
  • 如何分析C++实现功能齐全的屏幕截图示例
    如何分析C++实现功能齐全的屏幕截图示例,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。屏幕截图已经成为了所有IM即时通讯软件的必备模块,也是日常办公中使用最频繁...
    99+
    2023-06-25
  • 原生JS怎么实现简单屏幕截图
    这篇文章主要介绍“原生JS怎么实现简单屏幕截图”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“原生JS怎么实现简单屏幕截图”文章能帮助大家解决问题。了解 HTML5 中的 CanvasHTML5 中的...
    99+
    2023-07-06
  • Android 实现屏幕录制和截屏
    在移动开发中,实现屏幕录制和截屏是常见的需求。对于 Android 应用而言,实现屏幕录制和截屏可以帮助开发者更好地测试和调试自己的应用,同时还能够提供一些特定场景下的用户体验。 屏幕录制 Android 应用程序可以通过使用 MediaP...
    99+
    2023-08-18
    android 截屏 录屏
  • windows8如何截图?win8桌面全屏截图图文教程
    有时想做个教程,结果不知怎么截图,相信很多windows8用户都不知道windows8如何截图吧,几经琢磨终于找到截图快捷键。下面我们一起来看看windows8桌面全屏截图教程。 1、按下“Wi...
    99+
    2022-06-04
    截图 全屏 桌面
  • Android屏幕及view的截图实例详解
    Android屏幕及view的截图实例详解屏幕可见区域的截图 整个屏幕截图的话可以用View view = getWindow().getDecorView();public static Bitmap getNormalViewScree...
    99+
    2023-05-31
    android view截图 roi
  • go语言实现屏幕截图的示例代码
    目录借助第三方库安装自定义截图 Capture全屏截图 CaptureDisplay获取活动显示器数量 NumActiveDisplays获取指定屏幕显示范围 GetDisplayB...
    99+
    2022-11-13
  • Java实现屏幕截图工具的代码分享
    目录效果展示程序结构核心代码效果展示 程序运行后的截图: 先测试一下功能: 截图过程对界面的捕捉: 双击保存后的显示界面: 后续的步骤就自己去尝试吧,这里给出了简单的测试过程。...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作