`
kzby2003
  • 浏览: 30015 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

C++截屏当前活动窗口保存成BMP文件以及BMP文件的比较

阅读更多
#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以内
分享到:
评论

相关推荐

    vs C++ 截屏为BMP图片,分割BMP图片

    在本文中,我们将深入探讨如何使用C++编程语言在Visual Studio 2019环境下实现屏幕截图并将其保存为BMP格式的图像,以及如何进一步分割这些BMP图片。首先,我们需要了解BMP文件格式的基本原理,然后我们将讨论C++中...

    C++实现截屏保存屏幕上的一块区域为.bmp文件

    总结来说,C++实现截屏保存为.bmp文件涉及了对操作系统底层API的调用、位图数据的处理以及文件I/O操作。这个过程不仅考验了编程技能,还要求对操作系统和图形编程有深入的理解。通过这样的实践,你可以更好地掌握C++...

    MFC截取窗体图片并保存BMP

    在本文中,我们将深入探讨如何在Visual Studio 2010环境下使用Microsoft Foundation Classes (MFC)库来截取窗体图像并将其保存为BMP文件。BMP(Bitmap)是一种常见的位图图像文件格式,它包含像素颜色信息,不进行...

    截屏并保存为bmp c++

    在IT领域,特别是编程与图形处理方面,"截屏并保存为bmp c++"这一主题涉及到了使用C++语言进行屏幕捕获,并将捕获到的图像以位图(.bmp)格式保存的重要技术点。下面,我们将深入探讨这一主题所包含的关键知识点。 ...

    C++截屏,bmp转jpg,jpg压缩

    本文将详细讲解如何使用C++实现这些功能,包括屏幕截取、BMP到JPG的转换以及JPEG的压缩。 首先,我们要了解C++中实现屏幕截取的基本步骤。屏幕截取通常涉及操作系统级别的API调用,因为直接访问显示器的内存并不...

    VC++ 截屏软件,可保存为bmp图片

    综上所述,这个VC++实现的截屏软件虽简单,但充分展示了C++在系统编程中的强大能力,包括屏幕捕获、文件保存、系统托盘交互以及快捷键处理等多方面技术。对于学习和研究Windows API编程的开发者来说,这是一个很好的...

    BMPlib.zip_C++ 截屏_DOS bmp_bmplib_截屏

    这个压缩包“BMPlib.zip”提供了一个C++实现的解决方案,用于在DOS下进行屏幕截屏并保存为BMP格式的图像文件。这种功能对于调试、监控或创建自定义的图形用户界面很有用。 首先,我们要理解BMP(Bitmap)文件格式。...

    C++获取并保存屏幕

    最后,我们可以使用`CreateDIBSection`创建一个位图,将内存DC的内容保存到位图中,并通过`SaveBitmapToFile`函数将其保存为PNG或BMP文件。 关键函数包括: - `GetDesktopWindow()`:获取桌面窗口句柄。 - `...

    visual c++游戏截屏_你是否发现了有的游戏按截屏键无法截屏因为是用DirectX写的硬件加速抓不了屏,必须用DX写个代码在游戏中截屏(附源代码).zip

    总之,解决DirectX硬件加速游戏的截屏问题需要对Direct3D有深入的理解,以及使用Visual C++编写底层图形代码的能力。通过学习和实践,开发者可以掌握这一技术,不仅为自己的游戏添加截屏功能,也为调试和分享游戏...

    c++ 截取屏幕图片并保存

    以下是一个简单的C++代码示例,演示如何截取整个屏幕并保存为BMP文件: ```cpp #include #include void CaptureScreenAndSave(const char* filename) { // 获取桌面DC HDC desktop_dc = GetDC(NULL); // 创建...

    基于MFC桌面截屏保存为BMP和JPG图片格式代码实现

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC)库在Visual C++ 6.0环境下实现桌面截屏并保存为BMP和JPG图片格式。MFC是Microsoft提供的一种C++类库,它封装了Windows API,使得Windows应用程序...

    C++截屏程序源代码.zip

    C++截屏程序首先需要获取当前活动窗口的句柄(HWND),以便能够访问和操作屏幕。这通常通过Windows API函数`FindWindow`或`GetForegroundWindow`来实现。之后,通过`GetWindowDC`或`GetDesktopWindow`获取桌面设备...

    vc c++ usb摄像头截屏

    在VC++环境中,USB摄像头截屏涉及到的主要知识点包括C++编程、Windows API调用、设备驱动接口、图像处理以及文件存储。以下是对这些关键领域的详细解释: 1. **C++编程**:C++是一种强大的面向对象编程语言,适用于...

    C++ 截屏源码

    在实际开发中,除了基本的截取全屏外,还可以根据需求扩展,比如只截取活动窗口、支持自定义区域截图、添加拖拽选择等功能。此外,如果使用DirectX,性能可能会有所提升,但代码会更复杂,因为DirectX主要用于高性能...

    指定窗口截图,窗口句柄截图

    7. **保存截图到文件**:现在,内存DC中的位图已经包含了窗口的图像,我们可以使用`SaveImage`函数(非标准Windows API,可能需要自定义实现),将位图保存为常见的图像文件格式,如BMP、JPEG或PNG。 8. **清理资源...

    QQ 截屏源代码 C++

    1. **窗口句柄获取**:首先,需要获取当前活动窗口的句柄,以便确定截图的范围。在Windows系统中,可以使用`FindWindow`和`GetWindowRect`等API函数来获取这些信息。 2. **设备上下文(Device Context, DC)**:...

    十行代码实现屏幕截图并保存为jpg、png、bmp等格式文件

    Microsoft Visual Studio 2008 控制台应用程序,使用MFC或者ATL实现。 截图保存在程序运行所在的目录。截取整个屏幕。 重要的是原理,自己可以实现比如截取窗口或者特定区域的画面。

    C++开发截屏小程序

    在C++编程环境中,开发一个Win32截屏小程序是一个涉及多方面技术的任务。这个小程序主要功能是捕获屏幕上的图像,并允许用户保存所选区域。在这个过程中,我们需要利用Windows API,尤其是Win32 API,以及图形设备...

    GXDI截屏.rar_GXDI_dxgi_dxgi截图 c++_dxgi截屏_gxdi是什么意思

    标题中的“GXDI截屏.rar”是一个压缩包文件,它包含与使用DXGI(DirectX Graphics Infrastructure)在C++环境中实现屏幕截图相关的资源。DXGI是Microsoft DirectX的一部分,主要用于管理和交换图形数据,它提供了一...

    C++ MFC中一段屏幕截屏的函数

    整体屏幕截图即截取整个桌面或当前窗口的画面。在MFC中,可以通过创建兼容的设备上下文(Device Context, DC)来完成这一操作。 ##### 代码解析 ```cpp void CMainFrame::OnCutscreen() { // 获取桌面DC HDC hDC ...

Global site tag (gtag.js) - Google Analytics