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
",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; } }

速度はまだ良くて、2枚の1024*768のピクチャーを比較して、200 ms以内を費やします