더북(TheBook)

3.4.1 DIB 화면 출력 함수(SetDIBitsToDevice와 StretchDIBits)

Windows API는 DIB(장치 독립 비트맵)를 화면에 출력하기 위한 두 개의 함수를 지원한다. 하나는 비트맵을 원본 크기 그대로 화면에 출력하는 SetDIBitsToDevice 함수이고, 다른 하나는 비트맵을 원하는 크기로 확대 또는 축소시켜서 화면에 출력할 수 있는 StretchDIBits 함수이다.

먼저 비트맵을 원본 크기 그대로 출력하는 SetDIBitsToDevice 함수에 대하여 알아보자. SetDIBitsToDevice 함수의 원형은 다음과 같다.

int SetDIBitsToDevice(
    HDC hdc,                 // 출력 대상의 DC 핸들
    int XDest,               // 출력 대상의 좌상귀 x 좌표
    int YDest,               // 출력 대상의 좌상귀 y 좌표
    DWORD dwWidth,           // DIB 원본 사각형 너비(가로 픽셀 크기)
    DWORD dwHeight,          // DIB 원본 사각형 높이(세로 픽셀 크기)
    int XSrc,                // DIB 원본의 좌상귀 x 좌표
    int YSrc,                // DIB 원본의 좌상귀 y 좌표
    UINT uStartScan,         // 첫 번째 스캔 라인
    UINT cScanLines,         // 출력할 스캔 라인의 개수
    CONST VOID *lpvBits,     // 픽셀 데이터 시작 주소
    CONST BITMAPINFO *lpbmi, // BITMAPINFO 구조체 시작 주소
    UINT fuColorUse          // RGB 또는 색상 테이블 인덱스
);

SetDIBitsToDevice 함수는 꽤 많은 인자를 필요로 하며, 각각의 인자에 대한 설명은 함수 원형 오른편에 주석 형태로 적어두었다. 주석에 쓰여 있는 출력 대상이라는 것은 비트맵을 나타낼 윈도우를 의미하고, 해당 윈도우의 DC 핸들 값을 SetDIBitsToDevice 함수의 첫 번째 인자로 전달해야 한다. 기본적으로 이 함수는 입력 DIB 픽셀 데이터의 (XSrc, YSrc) 좌표로부터 가로 dwWidth, 세로 dwHeight 크기만큼의 사각형 영역을 출력 대상 좌표 (XDest, YDest)에 동일 크기로 출력한다. 비트맵 전체를 출력하는 경우 uStartScan은 0이고, cScanLinesdwHeight와 동일하다. XSrc, YSrc, uStartScan, cScanLines 등을 적절하게 조합하여 원본 비트맵의 전체 또는 일부분만 출력할 수도 있다. lpvBits는 픽셀 데이터의 시작 주소를 받는다. lpbmiBITMAPINFOHEADER 구조체의 시작 주소를 넘겨주면 된다. 마지막으로 fuColorUse는 DIB 출력 시 색상 테이블 사용 방식을 지정하는데, 보통 DIB_RGB_COLORS를 지정하면 된다.

사실 lpbmi는 BITMAPINFOHEADER 구조체의 주소라기보다는 BITMAPINFO라는 구조체의 시작 주소를 의미한다. BITMAPINFO 구조체는 wingdi.h 파일에 아래와 같이 정의되어 있다.

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;

즉, BITMAPINFO는 BITMAPINFOHEADER와 색상 테이블 정보를 묶어서 만들어진 구조체라고 할 수 있으며, 결국 BITMAPINFOHEADER 시작 위치는 BITMAPINFO 구조체 시작 위치와 동일하다. 그러므로 포인터 변수의 형변환 연산자만 (BITMAPINFO*) 형태로 붙여주면 BITMAPINFOHEADER 시작 주소와 동일하게 사용할 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.