2009년 11월 5일 목요일

MFC 화면 캡쳐, BMP로 저장

// 스크린 전체를 캡쳐하기 위해서 CWindowDC 형식으로 DC를 얻는다.
// GetDC의 파라메터에 특정 윈도우 핸들을 넣지 않고 NULL을 넣으면
// CWindowDC 형식으로 DC를 얻게 된다.

HDC h_screen_dc = ::GetDC(NULL);
 
// 현재 스크린의 해상도를 얻는다.
int width = ::GetDeviceCaps(h_screen_dc, HORZRES);
int height = ::GetDeviceCaps(h_screen_dc, VERTRES);
 
// DIB의 형식을 정의한다.
BITMAPINFO dib_define;
dib_define.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dib_define.bmiHeader.biWidth = width;
dib_define.bmiHeader.biHeight = height;
dib_define.bmiHeader.biPlanes = 1;
dib_define.bmiHeader.biBitCount = 24;
dib_define.bmiHeader.biCompression = BI_RGB;
dib_define.bmiHeader.biSizeImage = (((width * 24 + 31) & ~31) >> 3) * height;
dib_define.bmiHeader.biXPelsPerMeter = 0;
dib_define.bmiHeader.biYPelsPerMeter = 0;
dib_define.bmiHeader.biClrImportant = 0;
dib_define.bmiHeader.biClrUsed = 0;
 
// DIB의 내부 이미지 비트 패턴을 참조할 포인터 변수
BYTE *p_image_data = NULL;
 
// dib_define에 정의된 내용으로 DIB를 생성한다.
HBITMAP h_bitmap = ::CreateDIBSection(h_screen_dc, &dib_define, DIB_RGB_COLORS, (void **)&p_image_data, 0, 0);
 
// 이미지를 추출하기 위해서 가상 DC를 생성한다. 메인 DC에서는 직접적으로 비트맵에 접근하여
// 이미지 패턴을 얻을 수 없기 때문이다.
HDC h_memory_dc = ::CreateCompatibleDC(h_screen_dc);
 
// 가상 DC에 이미지를 추출할 비트맵을 연결한다.
HBITMAP h_old_bitmap = (HBITMAP)::SelectObject(h_memory_dc, h_bitmap);
 
// 현재 스크린 화면을 캡쳐한다.
::BitBlt(h_memory_dc, 0, 0, width, height, h_screen_dc, 0, 0, SRCCOPY);
 
// 본래의 비트맵으로 복구한다.
::SelectObject(h_memory_dc, h_old_bitmap);
 
// 가상 DC를 제거한다.
DeleteDC(h_memory_dc);
 
// DIB 파일의 헤더 내용을 구성한다.
BITMAPFILEHEADER dib_format_layout;
ZeroMemory(&dib_format_layout, sizeof(BITMAPFILEHEADER));
dib_format_layout.bfType = *(WORD*)"BM";
dib_format_layout.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dib_define.bmiHeader.biSizeImage;
dib_format_layout.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

//현재 디렉토리에서 한 순위를 내려간후 [data]\\save\\ 폴더에 저장
 CString directory;
 char* savePath;

 directory = L"..\\[data]\\save\\" + DoS + L"_" + Name + L".bmp";
 USES_CONVERSION;
 savePath = W2A(directory.GetString());
 

// DIB 파일을 생성한다.
FILE *p_file = fopen("image.bmp", "wb");
if(p_file != NULL){
    fwrite(&dib_format_layout, 1, sizeof(BITMAPFILEHEADER), p_file);
    fwrite(&dib_define, 1, sizeof(BITMAPINFOHEADER), p_file);
    fwrite(p_image_data, 1, dib_define.bmiHeader.biSizeImage, p_file);
    fclose(p_file);
}
 
// 사용했던 비트맵과 DC 를 해제한다.
if(NULL != h_bitmap) DeleteObject(h_bitmap);
if(NULL != h_screen_dc) ::ReleaseDC(NULL, h_screen_dc);

댓글 없음:

댓글 쓰기