.스트레칭 모드

비트맵 삽입 기능이 동작하는지 여러 종류의 비트맵을 삽입해 보자. DIB에는 장치에 상관없이 출력할 있는 정보가 모두 포함되어 있으므로 아무 비트맵이나 선택해도 삽입될 것이며 트래커로 크기를 변경해 보면 크기도 바뀐다. 그런데 컬러 비트맵을 삽입한 작게 축소하면 그림에 잔상이 많이 생기고 전반적으로 어두워지는 것을 확인할 있다. 이렇게 되는 이유는 디폴트 스트레칭 모드가 BLACKONWHITE 되어 있어 가급적 검정색을 유지하도록 되어 있기 때문이다. OnPaint 다음 코드를 추가해 보자.

 

LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   ....

   SetStretchBltMode(hMemDC,COLORONCOLOR);

   for (idx=0;idx<arNum;idx++) {

   ....

 

도형을 그리는 루프로 진입하기 전에 스트레칭 모드를 COLORONCOLOR 바꾸면 축소시 훨씬 깔끔한 모양의 이미지가 출력된다. COLORONCOLOR 별다른 논리 연산없이 단위로 삭제하기 때문에 컬러 이미지를 축소할 때는 훨씬 품질이 좋다. 다음은 HALFTONE으로 스트레칭 모드를 바꿔 보고 모드의 결과를 비교해 보자. HALFTONE 주변 픽셀의 정보까지 고려하여 이미지를 확대, 축소하므로 시간이 조금 오래 걸리기는 하지만 훨씬 좋은 이미지를 만든다.

물론 모드는 컬러 이미지일 경우에만 좋은 결과를 보여 주며 흑백 이미지인 경우는 모드보다 BLACKONWHITE, WHITEONBLACK 좋은 선택이 것이다. 하지만 요즘 흑백 이미지는 보기 드물므로 가급적 컬러 이미지를 보기 좋게 출력하는 것이 좋다. 가지 모드 HALFTONE 품질이 좋으므로 약간의 속도 감소를 고려하더라도 HALFTONE 선택하는 것이 현명하다.

그러나 문제가 있는데 HALFTONE 98에서는 지원되지 않으며 NT 이상에서만 지원된다는 점이다. 그래서 98에서는 COLORONCOLOR, NT 이상에서는 HALFTONE 모드를 쓰는 것이 가장 합리적이다. 전역 변수 StretchMode 변수를 추가하고 메인 윈도우가 생성될 운영체제의 버전에 따라 스트레칭 모드를 미리 선택한 OnPaint에서 모드를 사용하도록 수정한다.

 

int StretchMode;

....

LRESULT Main_OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   OSVERSIONINFO osv;

  

   osv.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);

   GetVersionEx(&osv);

   if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {

      StretchMode=HALFTONE;

   } else {

      StretchMode=COLORONCOLOR;

   }

   ....

 

LRESULT OnPaint(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   ....

   SetStretchBltMode(hMemDC,StretchMode);

   for (idx=0;idx<arNum;idx++) {

   ....

 

이렇게 하면 NT/2000에서는 가장 품질이 좋은 HALFTONE 스트레칭 모드를 사용할 것이고 모드를 지원하지 않는 95/98에서는 COLORONCOLOR 스트레칭 모드가 대신 사용되어 운영체제의 지원을 최대한으로 받을 있다. OnPaint에서 스트레칭 모드를 직접 선택하지 않고 별도의 전역 변수를 사용하는 이유는 가급적이면 그리는 시간을 단축하기 위해서이다. 실행중에 운영체제가 바뀔 리는 절대로 없으니 그릴 때마다 운영체제의 버전을 매번 조사할 필요는 없는 것이다. OnPaint 아주 자주 호출되는 함수이므로 가급적이면 빨리 처리해야 한다.

스트레칭 모드에 따라 출력 품질에 어떤 차이점이 있는지 비교해 보고 싶다면 모드를 바꿔 가며 비트맵을 여러 출력해 보면 된다. 그러나 소스를 일일이 고쳐 가면서 이전 출력과 새로운 출력을 비교한다는 것은 굉장히 번거롭고 한눈에 차이점을 비교하기도 무척 어렵다. 이럴 때는 스트레칭 모드를 바꿔 가며 출력하는 간단한 테스트 코드를 작성하고 실시간으로 결과를 비교하는 방법을 있다. OnKeyDown 선두에 다음 임시 코드를 작성해 보자.

 

LRESULT OnKeyDown(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   char str[128];

   switch (wParam) {

   case VK_F1:StretchMode=BLACKONWHITE;lstrcpy(str,"BLACKONWHITE");break;

   case VK_F2:StretchMode=WHITEONBLACK;lstrcpy(str,"WHITEONBLACK");break;

   case VK_F3:StretchMode=COLORONCOLOR;lstrcpy(str,"COLORONCOLOR");break;

   case VK_F4:StretchMode=HALFTONE;lstrcpy(str,"HALFTONE");break;

   }

   SetWindowText(GetParent(hWnd),str);

   InvalidateRect(hWnd,NULL,FALSE);

   return 0;

   ....

 

눌러진 펑션키에 따라 스트레칭 모드를 바꾸고 다시 그리도록 했으므로 비트맵을 축소해 놓은 상태로 펑션키를 눌러 보면 차이점을 관찰해볼 있을 것이다. API 함수의 다양한 플래그들은 이런 식으로 스스로 비교해 보면서 경험해 보는 것이 좋다. 옛날 속담의 백독이 불여일타가 이런 경우를 두고 하는 말이다. 코드는 어디까지나 테스트를 위한 임시코드이므로 비교가 끝난 후는 삭제하도록 하자.