더북(TheBook)

이로써 BMP 파일로부터 DIB 정보를 읽어오는 작업은 완료되었고, 이제 이 DIB 비트맵을 화면에 출력하는 코드를 만들어볼 차례이다. 비트맵 화면 출력은 SetDIBitsToDevice 함수를 사용할 것이며, 이때 실제 비트맵 픽셀 데이터의 시작 위치를 함수의 인자로 넘겨주어야 한다. 픽셀 데이터 시작 위치는 아래 코드 형태로 구할 수 있다.

LPVOID lpvBits;
if (nBitCount = = 24)
    lpvBits = pDib + sizeof(BITMAPINFOHEADER);
else
    lpvBits = pDib + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << nBitCount);

pDib 변수가 가리키는 위치가 BITMAPINFOHEADER 시작 주소이다. 그러므로 트루컬러 비트맵은 단순히 pDib에 BITMAPINFOHEADER 크기를 더하면 픽셀 데이터 위치가 된다. 그레이스케일 비트맵이라면 색상 테이블 크기만큼을 추가로 더해줘야 한다. 이제 SetDIBitsToDevice 함수를 호출할 수 있는 준비가 다 되었으니 아래와 같이 화면 출력 코드를 작성해보자.

CClientDC dc(this);
::SetDIBitsToDevice(dc.m_hDC, point.x, point.y, nWidth, nHeight, 0, 0, 0,
    nHeight, lpvBits, (BITMAPINFO*)pDib, DIB_RGB_COLORS);

CClientDC 클래스는 MFC에서 윈도우의 디바이스 컨텍스트(DC)를 쉽게 받아오는 것을 도와주는 클래스이다. 보통 CClientDC dc(this);의 형태로 사용되어, 해당 윈도우의 디바이스 컨텍스트 정보를 dc 변수로 받을 수 있다. 이때 DC 핸들 값은 dc.m_hDC 형태로 참조할 수 있다. 비트맵을 화면에 출력하는 함수는 SetDIBitsToDevice 함수를 사용하였다. 이 함수에서 첫 번째 인자는 디바이스 컨텍스트의 핸들을 받기 때문에 dc.m_hDC를 입력하였다. 두 번째와 세 번째 인자로 OnLButtonDown 함수의 인자로 넘어온 좌표를 넘겨주었기 때문에, 마우스가 클릭한 위치에 lenna.bmp 비트맵이 출력될 것이다.

이제 화면 출력까지 모두 완료되었다. 다만 OnLButtonDown 함수가 종료되기 전에 앞에서 작업한 사항들을 정리할 필요가 있다. 동적 할당한 메모리 공간을 해제해야 하고, 파일을 열었던 것을 다시 닫아주어야 한다. new 연산자에서 []를 이용하여 할당한 메모리 공간은 해제할 때에도 delete[]를 붙여야 함을 명심하라.

delete[] pDib;
fclose(fp);
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.