C++スクリーンショット現在アクティブなウィンドウをBMPファイルとBMPファイルの比較に保存
5109 ワード
#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以内を費やします