나는 hwnd를 ppm 파일로 저장하는 기능이 있습니다. 이 함수는 msdn 예제에서 영감을 얻었습니다. msdn 샘플과 내 함수 모두 작동하지만 ... 문제가 있습니다 ...hwnd에서 ppm으로 발행
하지만 먼저 여기에 함수가 있습니다. 당신이 볼 수 있듯이, 폭 크기에 문제가
http://imageshack.us/photo/my-images/853/test2ne.jpg/
: 그래서 여기
int CaptureAnImage(HWND hWnd)
{
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
RECT rc;
BITMAPINFOHEADER bi;
DWORD dwBmpSize;
HANDLE hDIB;
char *lpbitmap;
int w, h;
FILE *f;
// Retrieve the handle to a display device context for the client
// area of the window.
hdcWindow = GetDC(hWnd);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if(!hdcMemDC) {
MessageBox(hWnd, "CreateCompatibleDC has failed","Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
GetClientRect(hWnd, &rc);
w = rc.right - rc.left;
h=rc.bottom-rc.top;
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow, w, h);
if(!hbmScreen) {
MessageBox(hWnd, "CreateCompatibleBitmap Failed","Failed", MB_OK);
goto done;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);
// Bit block transfer into our compatible memory DC.
if(!BitBlt(hdcMemDC,
0,0,
w, h,
hdcWindow,
0,0,
SRCCOPY)) {
MessageBox(hWnd, "BitBlt has failed", "Failed", MB_OK);
goto done;
}
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = w;
bi.biHeight = h;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmpSize = w*bi.biBitCount*h;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
hDIB = GlobalAlloc(GHND,dwBmpSize);
lpbitmap = (char *)GlobalLock(hDIB);
// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbitmap.
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)h,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
f = fopen("./test.ppm", "wb");
if (!f) {
fprintf(stderr, "cannot create ppm file\n");
goto done;
}
fprintf(f, "P6\n%d %d\n255\n", w, h);
fwrite((LPSTR)lpbitmap, dwBmpSize, 1, f);
fclose(f);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(hWnd,hdcWindow);
return 0;
}
결과 이미지입니다. 어쩌면 창문 경계 때문일까? 코드에서 "w = rc.right - rc.left;"를 변경합니다. "w = rc.right - rc.left - 10;"으로 변경하는 것이 좋습니다. 그러나 (어쩌면 10 픽셀?) 나는 "-10"나는 넣어야 할 이유를 이해하지 않고 ... 일부 픽셀은 화면의 오른쪽에 누락
http://imageshack.us/photo/my-images/207/test3jq.jpg
그리고 마지막 질문 : 를 GetDIBits 함수에 역순으로 내 바이트를 넣을 수있는 방법이 있습니까? 픽셀 단위의 비용을 지불해야하므로 픽셀 단위로 복사하지 않아도됩니다. (오케이,이 파일을 디스크에 저장하고 있기 때문에 CPU 시간에 신경 쓸 필요는 없지만 디스크에이 그림을 저장하는 것이 목표가 아닙니다. 디버그 목적으로 만 사용하고 있습니다) 어떤 도움
윈도우 기반 코드로 C 표준 라이브러리를 혼합하는 것은 정말 나쁜 생각입니다 ... – perilbrain
왜이게 나쁜가요? 나는 C로 코딩하는 데 익숙하다. (C++이 아니다.) 윈도우 라이브러리는 C 언어로 사용 가능하다. – ramone
http://stackoverflow.com/questions/2185944/why-must-stride-in-the-system-drawing-bitmap-constructor-be-a-multiple-of-4 –