OpenGL로 구현한 프로그램에 화면 캡쳐 기능이 필요해서 오동님 블로그를 참조해서 사용하다가 리눅스(Qt)에서도 사용하게 될 일이 있어서 수정한 거 올립니다. 확인 결과 MFC, Win32 API 에서 문제 없이 잘 동작하며 리눅스에의 확인은 제 친구가 했는 데 리눅스에서도 문제 없이 잘 동작한다고 하네요.(비트맵 관련 구조체가 없어서 구조체는 직접 추가했다고 함)
void ScreenCapture( const char *strFilePath )
{
//비트맵 파일 처리를 위한 헤더 구조체
BITMAPFILEHEADER BMFH;
BITMAPINFOHEADER BMIH;
int nWidth = 0;
int nHeight = 0;
unsigned long dwQuadrupleWidth = 0; //LJH 추가, 가로 사이즈가 4의 배수가 아니라면 4의 배수로 만들어서 저장
GLbyte *pPixelData = NULL; //front buffer의 픽셀 값들을 얻어 오기 위한 버퍼의 포인터
#ifdef WIN32
//윈도우의 클라이언트 영역 좌표
RECT ImageRect;
GetClientRect( *m_hWndCopy, &ImageRect );
//이미지 영역 좌표를 이용하여 실제 이미지의 사이즈를 계산
nWidth = ImageRect.right - ImageRect.left; //윈도우 버전의 경우 사이즈 변경이 되므로 그때그때 조사
nHeight = ImageRect.bottom - ImageRect.top;
#else
nWidth = 1024; //(나의 경우)리눅스에서의 경우 해상도 고정이므로 그 값을 입력
nHeight = 768;
#endif
//4의 배수인지 아닌지 확인해서 4의 배수가 아니라면 4의 배수로 맞춰준다.
dwQuadrupleWidth = ( nWidth % 4 ) ? ( ( nWidth ) + ( 4 - ( nWidth % 4 ) ) ) : ( nWidth );
//비트맵 파일 헤더 처리
BMFH.bfType = 0x4D42; //B(42)와 M(4D)에 해당하는 ASCII 값을 넣어준다.
//바이트 단위로 전체파일 크기
BMFH.bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + ( dwQuadrupleWidth * 3 * nHeight );
//영상 데이터 위치까지의 거리
BMFH.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
//비트맵 인포 헤더 처리
BMIH.biSize = sizeof( BITMAPINFOHEADER ); //이 구조체의 크기
BMIH.biWidth = nWidth; //픽셀 단위로 영상의 폭
BMIH.biHeight = nHeight; //영상의 높이
BMIH.biPlanes = 1; //비트 플레인 수(항상 1)
BMIH.biBitCount = 24; //픽셀당 비트수(컬러, 흑백 구별)
BMIH.biCompression = BI_RGB; //압축 유무
BMIH.biSizeImage = dwQuadrupleWidth * 3 * nHeight; //영상의 크기
BMIH.biXPelsPerMeter = 0; //가로 해상도
BMIH.biYPelsPerMeter = 0; //세로 해상도
BMIH.biClrUsed = 0; //실제 사용 색상수
BMIH.biClrImportant = 0; //중요한 색상 인덱스
pPixelData = new GLbyte[ dwQuadrupleWidth * 3 * nHeight ]; //LJH 수정
//프런트 버퍼로 부터 픽셀 정보들을 얻어온다.
glReadPixels(
0, 0, //캡처할 영역의 좌측상단 좌표
nWidth, nHeight, //캡처할 영역의 크기
GL_BGR, //캡처한 이미지의 픽셀 포맷
GL_UNSIGNED_BYTE, //캡처한 이미지의 데이터 포맷
pPixelData //캡처한 이미지의 정보를 담아둘 버퍼 포인터
);
{//저장 부분
FILE *outFile = fopen( strFilePath, "wb" );
if( outFile == NULL )
{
//에러 처리
//printf( "에러" );
//fclose( outFile );
}
fwrite( &BMFH, sizeof( char ), sizeof(BITMAPFILEHEADER), outFile ); //파일 헤더 쓰기
fwrite( &BMIH, sizeof( char ), sizeof(BITMAPINFOHEADER), outFile ); //인포 헤더 쓰기
fwrite( pPixelData, sizeof( unsigned char ), BMIH.biSizeImage, outFile ); //glReadPixels로 읽은 데이터 쓰기
fclose( outFile ); //파일 닫기
}
if ( pPixelData != NULL )
{
delete pPixelData;
}
}
아래는 위의 함수로 저장한 bmp파일들입니다.