先判断上次键盘鼠标活动时间,如果时间较长则隔一段时间截屏判断是否在看视频,如果图片符合相似度则执行待机操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | #include <windows.h> #include "bitmap.h" #include "stdio.h" #include <time.h> #include <stdlib.h> #include <PowrProf.h> #include <math.h> void echo( CHAR *str); int getlastinput(); int CheckFullscreen(); int CaptureImage( CHAR *lpbitmap, int width, int height); int save( char *outfile, CHAR *lpbitmap, DWORD dwBmpSize, int width, int height); void echo( CHAR *str) { //MessageBox(NULL, str, NULL, MB_OK); time_t t1; struct tm *newtime; char time_str[128]; t1 = time (NULL); newtime= localtime (&t1); strftime (time_str, 128, "%Y%m%d_%H%M%S" , newtime); printf ( "%s: %s \n" , time_str, str); //printf("%s \n", str); } int main( int argc, char *argv[]) { INT width = GetSystemMetrics(SM_CXSCREEN); // 屏幕宽 INT height = GetSystemMetrics(SM_CYSCREEN); // 屏幕高 DWORD dwBmpSize = width * height * 4; INT WidthBytes = width * 4; if (argc == 1) { printf ( "use sleep_time(sec) idle_time(min) similarity(<100) save_bmp(1) debug(1)\n" ); exit (1); } int sleep_idle, sleep_time, idle_time, save_bmp, debug; sleep_idle = sleep_time = idle_time = save_bmp = debug = 0; float similarity = 0; if (argc > 1) sleep_time = atoi (argv[1]); if (argc > 2) idle_time = atoi (argv[2]); if (argc > 3) similarity = atof (argv[3]); if (argc > 4) save_bmp = atoi (argv[4]); if (argc > 5) debug = atoi (argv[5]); if (!sleep_time && !idle_time) { exit (1); } if (sleep_time >= 30) { sleep_idle = round(sleep_time/5); printf ( "sleep_idle = %d\n" , sleep_idle); sleep_idle = sleep_idle * 1000; } else { sleep_idle = sleep_time * 1000; } sleep_time = sleep_time * 1000; //sec idle_time = idle_time * 60 * 1000; //min HANDLE hDIB; hDIB = GlobalAlloc(GHND, dwBmpSize); CHAR *lpbitmap = ( char *)GlobalLock(hDIB); HANDLE hDIB2; hDIB2 = GlobalAlloc(GHND, dwBmpSize); CHAR *lpbitmap2 = ( char *)GlobalLock(hDIB2); if (!CaptureImage(lpbitmap, width, height)) { exit (1); } while (1) { //CheckFullscreen(); long int idle = getlastinput(); printf ( "%d \n" , idle); if (!debug && idle < idle_time) { echo ( "idle" ); Sleep(sleep_idle); continue ; } if (!CaptureImage(lpbitmap2, width,height)) { Sleep(5*1000); continue ; } int count = 0; int cmp = 0; int index = 0; for ( int i = 0;i < width;++i) { for ( int j = 0;j < height;++j) { count++; index = i * 4 + j * WidthBytes; if (lpbitmap[index + 2] != lpbitmap2[index + 2] || lpbitmap[index + 1] != lpbitmap2[index + 1] || lpbitmap[index + 0] != lpbitmap2[index + 0]) { cmp++; } //BYTE r = lpbitmap[index + 2]; //BYTE g = lpbitmap[index + 1]; //BYTE b = lpbitmap[index + 0]; //printf("r = %d\n", r ); //printf("g = %d\n", g ); //printf("b = %d\n", b ); //printf("index = %d\n", index); //Sleep(1000); } } printf ( "count = %d\n" , count); printf ( "cmp = %d\n" , cmp); float percentage = ( float )cmp / count * 100.0; printf ( "Percentage = %.2f%%\n" , percentage); if (!debug && percentage <= similarity) { echo( "SetSuspendState" ); SetSuspendState(0, 1, 1); Sleep(60*1000); } if (save_bmp == 1 && percentage <= similarity) { time_t t1; struct tm *newtime; char time_str[128]; char outfile[128]; t1 = time (NULL); newtime= localtime (&t1); //strftime(outfile, 128, "%Y%m%d_%H%M%S.bmp", newtime); strftime (time_str, 128, "%Y%m%d_%H%M%S" , newtime); sprintf (outfile, "%s_1_%.2f%%.bmp" ,time_str,percentage); save(outfile,lpbitmap, dwBmpSize, width, height); sprintf (outfile, "%s_2_%.2f%%.bmp" ,time_str,percentage); save(outfile,lpbitmap2, dwBmpSize, width,height); } memcpy (lpbitmap, lpbitmap2, dwBmpSize); Sleep(sleep_time); } // 解锁堆内存并释放 GlobalUnlock(hDIB); GlobalFree(hDIB); GlobalUnlock(hDIB2); GlobalFree(hDIB2); return 0; } int CaptureImage( CHAR *lpbitmap, int width, int height) { int ret = 1; //GetDesktopWindow() HDC hScreenDC = GetDC(NULL); //获取显示设备上下文环境 HDC hMemoryDC = CreateCompatibleDC(hScreenDC); // 创建与显示设备兼容的内存下文环境(设备描述表) if (!hMemoryDC) { echo(TEXT( "CreateCompatibleDC has failed" )); ret = 0; goto done; } //创建一个与显示设备描述表兼容的位图 HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); if (!hBitmap) { echo(TEXT( "CreateCompatibleBitmap Failed" )); ret = 0; goto done; } //把位图选到内存设备描述表中 SelectObject(hMemoryDC, hBitmap); //HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap); //把屏幕设备描述表拷贝到内存设备描述表中。 if (!BitBlt( hMemoryDC, // 目的DC 0, 0, // 目的DC的 x,y 坐标 width, height, // 目的 DC 的宽高 hScreenDC, // 来源DC 0, 0, // 来源DC的 x,y 坐标 SRCCOPY)) // 粘贴方式 { echo(TEXT( "BitBlt has failed" )); ret = 0; goto done; } //BITMAP bmpScreen; //Get the BITMAP from the HBITMAP //GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen); //hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap); BITMAPINFOHEADER bi; bi.biSize = sizeof (BITMAPINFOHEADER); bi.biWidth = width; bi.biHeight = height; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中. GetDIBits( hScreenDC, // 设备环境句柄 hBitmap, // 位图句柄 0, // 指定检索的第一个扫描线 ( UINT )height, // 指定检索的扫描线数 lpbitmap, // 指向用来检索位图数据的缓冲区的指针 (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式 DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成 ); //printf("sizeof((LPSTR)lpbitmap) = %d\n", sizeof((LPSTR)lpbitmap)); //printf("sizeof(lpbitmap[0]) = %d\n", sizeof(lpbitmap[0])); done: DeleteObject(hBitmap); DeleteObject(hMemoryDC); //DeleteDC(hMemoryDC); ReleaseDC(NULL, hScreenDC); return ret; } int getlastinput() { long int newTicks; // time value for new ticks long int inputTicks; // time value for current time long int elapsedTicks; // time value for elapsed time LASTINPUTINFO lii; // Structure for Windows time stuff // Set size of lii.cbsize lii.cbSize = sizeof (lii); // Get the time of the most recent (new) user input GetLastInputInfo(&lii); newTicks = lii.dwTime; inputTicks = GetTickCount(); elapsedTicks = inputTicks - newTicks; return elapsedTicks; } int CheckFullscreen() { int bFullScreen = 0; HWND hWnd = GetForegroundWindow(); RECT rcApp, rcDesk; GetWindowRect(GetDesktopWindow(), &rcDesk); if (hWnd!=GetDesktopWindow() && hWnd!=GetShellWindow()) { GetWindowRect(hWnd, &rcApp); if (rcApp.left<=rcDesk.left && rcApp.top<=rcDesk.top && rcApp.right>=rcDesk.right && rcApp.bottom>=rcDesk.bottom) { char wnd_name[256]; char wnd_title[256]; GetWindowText(hWnd,wnd_title, sizeof (wnd_title)); GetClassName(hWnd, wnd_name, sizeof (wnd_name)); printf ( "title: %s\n" , wnd_title); printf ( "name: %s\n" , wnd_name); if ( strcmp (wnd_name, "Windows.UI.Core.CoreWindow" ) != 0 && strcmp (wnd_name, "WorkerW" ) != 0){ bFullScreen =1; } } } return bFullScreen; } int save( char *outfile, CHAR *lpbitmap, DWORD dwBmpSize, int width, int height) { HANDLE hFile; DWORD dwSizeofDIB; DWORD dwBytesWritten; BITMAPFILEHEADER bmfHeader; BITMAPINFOHEADER bi; bi.biSize = sizeof (BITMAPINFOHEADER); bi.biWidth = width; bi.biHeight = height; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // 创建一个文件来保存文件截图 hFile = CreateFile( outfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); // 将 图片头(headers)的大小, 加上位图的大小来获得整个文件的大小 dwSizeofDIB = dwBmpSize + sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER); // 设置 Offset 偏移至位图的位(bitmap bits)实际开始的地方 bmfHeader.bfOffBits = ( DWORD ) sizeof (BITMAPFILEHEADER) + ( DWORD ) sizeof (BITMAPINFOHEADER); // 文件大小 bmfHeader.bfSize = dwSizeofDIB; // 位图的 bfType 必须是字符串 "BM" bmfHeader.bfType = 0x4D42; //BM dwBytesWritten = 0; WriteFile(hFile, ( LPSTR )&bmfHeader, sizeof (BITMAPFILEHEADER), &dwBytesWritten, NULL); WriteFile(hFile, ( LPSTR )&bi, sizeof (BITMAPINFOHEADER), &dwBytesWritten, NULL); WriteFile(hFile, ( LPSTR )lpbitmap, dwBmpSize, &dwBytesWritten, NULL); // 关闭文件句柄 CloseHandle(hFile); return 0; } |
使用tdm-gcc编译:
1 | gcc screen.c -o screen.exe -lgdi32 -lPowrprof |
参考:
https://docs.microsoft.com/zh-cn/windows/win32/gdi/capturing-an-image?redirectedfrom=MSDN
https://lellansin.wordpress.com/2014/03/16/c-gdi-%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE/
https://bbs.csdn.net/topics/390838652?page=4
https://bbs.csdn.net/topics/340205786?page=2
https://blog.csdn.net/haogeai123/article/details/7030583