OpenGL로 구현한 프로그램에 화면 캡쳐 기능이 필요해서 오동님 블로그를 참조해서 사용하다가

리눅스(Qt)에서도 사용하게 될 일이 있어서 수정한 거 올립니다.

확인 결과 MFC, Win32 API 에서 문제 없이 잘 동작하며 리눅스에의 확인은 제 친구가 했는 데

리눅스에서도 문제 없이 잘 동작한다고 하네요.(비트맵 관련 구조체가 없어서 구조체는 직접 추가했다고 함)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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파일들입니다.



'QT > OpenGL' 카테고리의 다른 글

Qt프로젝트에 OpenGL 사용하기  (0) 2015.04.13
OpenGL에서 팝업(Popup) 메뉴 사용하기  (0) 2015.04.08
QT에서 OpenGL 사용하기  (0) 2015.04.03
Posted by 모래반지빵냐빵냐
,