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파일들입니다.

'예제 모음 > 기타' 카테고리의 다른 글

OpenGL 화면 캡쳐해서 BMP 파일로 저장  (0) 2013.10.01

작성자

Posted by 사용자 오뇽

태그

댓글 영역