Win32でスクリーンキャプチャー
ちょっとわけあってデスクトップのスクリーンキャプチャを取得するプログラムを書いてみる.
まずは Win32 環境で.
- CreateDIBSection() で 32bit RGB な DIBSection を作る
- GetDesktopWindow() でデスクトップウィンドウ取ってくる
- BitBlt() でデスクトップウィンドウを DIBSection にコピー
- DIBSection はピクセルにアクセスできるのでそれを好きにいじる
簡単でよろしいです.上下逆っての以外は.
以下 PPM ASCII フォーマットに保存するサンプル.
/* * gcc capture_screen_win32.c -mwindows */ #include <stdio.h> #include <windows.h> #define IMAGE_FILE_PATH "capture_screen_win32.ppm" static void WriteImageToP3File(LPDWORD lpPixels, int width, int height, const char *file_path) { int x, y; LPDWORD lpPixel; FILE *file; file = fopen(file_path, "wb"); if (file != NULL) { fprintf(file, "P3\n"); fprintf(file, "%d %d\n", width, height); fprintf(file, "255\n"); for (y = height-1;y >= 0;y--) { lpPixel = lpPixels + (y * width); for (x = 0;x < width;x++) { fprintf(file, "%lu %lu %lu ", (*lpPixel & 0x00ff0000) >> 16, (*lpPixel & 0x0000ff00) >> 8, (*lpPixel & 0x000000ff) ); lpPixel++; } fprintf(file, "\n"); } fclose(file); } } int main(int argc, char *argv[]) { HWND hWndDesktop; HDC hDCDesktop; RECT rect; int width, height; BITMAPINFO bmpInfo; HBITMAP hBitmap; LPDWORD lpPixels; /* Get Desktop window and device context */ hWndDesktop = GetDesktopWindow(); hDCDesktop = GetDC(hWndDesktop); GetWindowRect(hWndDesktop, &rect); width = rect.right - rect.left; height = rect.bottom - rect.top; /* Create DIBSection */ bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = width; bmpInfo.bmiHeader.biHeight = height; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 32; bmpInfo.bmiHeader.biCompression = BI_RGB; hBitmap = CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, (void **)&lpPixels, NULL, 0); if (hBitmap != NULL && lpPixels != NULL ) { HDC hDC; /* Copy Desktop image to DIBSection */ hDC = CreateCompatibleDC(hDCDesktop); SelectObject(hDC, hBitmap); BitBlt(hDC, 0, 0, width, height, hDCDesktop, 0, 0, SRCCOPY); /* Write to PPM file */ WriteImageToP3File(lpPixels, width, height, IMAGE_FILE_PATH); DeleteDC(hDC); DeleteObject(hBitmap); } ReleaseDC(hWndDesktop, hDCDesktop); return 0; }