#include <time.h>
#include <afxwin.h>
#include <stdio.h>
#include <comdef.h>
#include <iostream>
#include <atlimage.h>
/*
* hwnd:要截图的窗口的句柄
* fileName:要比较的图片的路径
* offsets:有4个成员的int型数组,用于设置比较图片时,上、下、左、右的偏移量
* offsets[0]:左
* offsets[1]:上
* offsets[2]:右
* offsets[3]:下
*/
bool print_screen(HWND hwnd, const char* fileName, int offsets[])
{
LPCTSTR pFileName = NULL;
if(sizeof(TCHAR)==sizeof(char))
{
pFileName=(LPCTSTR)fileName;
}
else
{
int length= sizeof(TCHAR)*(strlen(fileName)+1);
LPTSTR tcBuffer=new TCHAR[length];
memset(tcBuffer,0,length);
MultiByteToWideChar(CP_ACP,0,fileName,strlen(fileName),tcBuffer,length);
pFileName=(LPCTSTR)tcBuffer ;
}
long t_start = ::GetTickCount();
CDC dc;
CDC *pDC = &dc;//屏幕DC
// HWND hwnd = ::GetForegroundWindow(); // 获得当前活动窗口
HDC activeDC = ::GetWindowDC(hwnd); //获得要截屏的窗口的hDC
pDC->Attach(activeDC);//获取当前活动窗口的DC
RECT rect;
::GetWindowRect(hwnd,&rect);//得到窗口的大小
int Width = rect.right - rect.left;
int Height = rect.bottom - rect.top;
/*cout << "Width:" << Width << endl
<< "Height:" << Height << endl << endl;*/
CDC memDC;//内存DC
memDC.CreateCompatibleDC(pDC);
CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap.CreateCompatibleBitmap(pDC, Width, Height);
oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC
memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY);//复制屏幕图像到内存DC
//以下代码保存memDC中的位图到文件
BITMAP bmp;
memBitmap.GetBitmap(&bmp);//获得位图信息
FILE *fp = fopen("C:\\abc.bmp", "w+b");
BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = bmp.bmBitsPixel;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头
byte * p = new byte[bmp.bmWidthBytes * bmp.bmHeight];//申请内存保存位图数据
GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, p,
(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//获取位图数据
fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);//写入位图数据
delete [] p;
fclose(fp);
// 以下代码用于比较指定的BMP文件与内存中的截图
CImage img;
img.Load(pFileName);
int nWidth = img.GetWidth();//获取图像宽度
int nHeight = img.GetHeight();//获取图像高度
if (Width != nWidth || Height != nHeight)
{
return false;
}
byte* pRealData;
pRealData=(byte*)img.GetBits();
int pit=img.GetPitch();
int bitCount=img.GetBPP()/8;
for (int y = offsets[1]; y < Height - offsets[3]; ++y)
{
for (int x = offsets[0]; x < Width - offsets[2]; ++x)
{
int pity = pit * y;
int pitx = x*bitCount;
if (up[bmp.bmWidth * (bmp.bmHeight - y - 1) + x] !=
(*(pRealData + pity + pitx + 2) << 16) + (*(pRealData + pity + pitx + 1) << 8) +
*(pRealData + pity + pitx))
{
printf("(%d, %d) = %x, ",x, y, up[bmp.bmWidth *
(bmp.bmHeight - y - 1) + x]);
printf("(%d, %d) = %x\n",x, y, (*(pRealData +
pity + pitx + 2) << 16) + (*(pRealData + pity + pitx + 1) << 8) + *(pRealData +
pity + pitx));
return false;
}
}
}
return true;
}
/*
* hwnd:要截图的窗口的句柄
* fileName:要比较的图片的路径
* left:比较图片时的左偏移量
* top:比较图片时的上偏移量
* right:比较图片时的右偏移量
* bottom:比较图片时的下偏移量
*/
int screenPrint(HWND hwnd, const char* fileName, int left, int top, int right, int bottom)
{
if (left < 0 || top < 0 || right < 0 || bottom < 0)
{
return -1;
}
int offsets[4];
offsets[0] = left;
offsets[1] = top;
offsets[2] = right;
offsets[3] = bottom;
bool isTheSame = print_screen(hwnd, fileName, offsets);
if (isTheSame)
{
return 0;
}
else
{
return -1;
}
}
速度尚可,比较两张1024 * 768的图片,耗时200ms以内
分享到:
相关推荐
在本文中,我们将深入探讨如何使用C++编程语言在Visual Studio 2019环境下实现屏幕截图并将其保存为BMP格式的图像,以及如何进一步分割这些BMP图片。首先,我们需要了解BMP文件格式的基本原理,然后我们将讨论C++中...
总结来说,C++实现截屏保存为.bmp文件涉及了对操作系统底层API的调用、位图数据的处理以及文件I/O操作。这个过程不仅考验了编程技能,还要求对操作系统和图形编程有深入的理解。通过这样的实践,你可以更好地掌握C++...
在本文中,我们将深入探讨如何在Visual Studio 2010环境下使用Microsoft Foundation Classes (MFC)库来截取窗体图像并将其保存为BMP文件。BMP(Bitmap)是一种常见的位图图像文件格式,它包含像素颜色信息,不进行...
在IT领域,特别是编程与图形处理方面,"截屏并保存为bmp c++"这一主题涉及到了使用C++语言进行屏幕捕获,并将捕获到的图像以位图(.bmp)格式保存的重要技术点。下面,我们将深入探讨这一主题所包含的关键知识点。 ...
本文将详细讲解如何使用C++实现这些功能,包括屏幕截取、BMP到JPG的转换以及JPEG的压缩。 首先,我们要了解C++中实现屏幕截取的基本步骤。屏幕截取通常涉及操作系统级别的API调用,因为直接访问显示器的内存并不...
综上所述,这个VC++实现的截屏软件虽简单,但充分展示了C++在系统编程中的强大能力,包括屏幕捕获、文件保存、系统托盘交互以及快捷键处理等多方面技术。对于学习和研究Windows API编程的开发者来说,这是一个很好的...
这个压缩包“BMPlib.zip”提供了一个C++实现的解决方案,用于在DOS下进行屏幕截屏并保存为BMP格式的图像文件。这种功能对于调试、监控或创建自定义的图形用户界面很有用。 首先,我们要理解BMP(Bitmap)文件格式。...
最后,我们可以使用`CreateDIBSection`创建一个位图,将内存DC的内容保存到位图中,并通过`SaveBitmapToFile`函数将其保存为PNG或BMP文件。 关键函数包括: - `GetDesktopWindow()`:获取桌面窗口句柄。 - `...
总之,解决DirectX硬件加速游戏的截屏问题需要对Direct3D有深入的理解,以及使用Visual C++编写底层图形代码的能力。通过学习和实践,开发者可以掌握这一技术,不仅为自己的游戏添加截屏功能,也为调试和分享游戏...
以下是一个简单的C++代码示例,演示如何截取整个屏幕并保存为BMP文件: ```cpp #include #include void CaptureScreenAndSave(const char* filename) { // 获取桌面DC HDC desktop_dc = GetDC(NULL); // 创建...
在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC)库在Visual C++ 6.0环境下实现桌面截屏并保存为BMP和JPG图片格式。MFC是Microsoft提供的一种C++类库,它封装了Windows API,使得Windows应用程序...
C++截屏程序首先需要获取当前活动窗口的句柄(HWND),以便能够访问和操作屏幕。这通常通过Windows API函数`FindWindow`或`GetForegroundWindow`来实现。之后,通过`GetWindowDC`或`GetDesktopWindow`获取桌面设备...
在VC++环境中,USB摄像头截屏涉及到的主要知识点包括C++编程、Windows API调用、设备驱动接口、图像处理以及文件存储。以下是对这些关键领域的详细解释: 1. **C++编程**:C++是一种强大的面向对象编程语言,适用于...
在实际开发中,除了基本的截取全屏外,还可以根据需求扩展,比如只截取活动窗口、支持自定义区域截图、添加拖拽选择等功能。此外,如果使用DirectX,性能可能会有所提升,但代码会更复杂,因为DirectX主要用于高性能...
7. **保存截图到文件**:现在,内存DC中的位图已经包含了窗口的图像,我们可以使用`SaveImage`函数(非标准Windows API,可能需要自定义实现),将位图保存为常见的图像文件格式,如BMP、JPEG或PNG。 8. **清理资源...
1. **窗口句柄获取**:首先,需要获取当前活动窗口的句柄,以便确定截图的范围。在Windows系统中,可以使用`FindWindow`和`GetWindowRect`等API函数来获取这些信息。 2. **设备上下文(Device Context, DC)**:...
Microsoft Visual Studio 2008 控制台应用程序,使用MFC或者ATL实现。 截图保存在程序运行所在的目录。截取整个屏幕。 重要的是原理,自己可以实现比如截取窗口或者特定区域的画面。
在C++编程环境中,开发一个Win32截屏小程序是一个涉及多方面技术的任务。这个小程序主要功能是捕获屏幕上的图像,并允许用户保存所选区域。在这个过程中,我们需要利用Windows API,尤其是Win32 API,以及图形设备...
标题中的“GXDI截屏.rar”是一个压缩包文件,它包含与使用DXGI(DirectX Graphics Infrastructure)在C++环境中实现屏幕截图相关的资源。DXGI是Microsoft DirectX的一部分,主要用于管理和交换图形数据,它提供了一...
整体屏幕截图即截取整个桌面或当前窗口的画面。在MFC中,可以通过创建兼容的设备上下文(Device Context, DC)来完成这一操作。 ##### 代码解析 ```cpp void CMainFrame::OnCutscreen() { // 获取桌面DC HDC hDC ...