예제 모음/기타
OpenGL 화면 캡쳐해서 BMP 파일로 저장
오뇽
2013. 10. 1. 14:39
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파일들입니다.