API-비트맵2(메모리DC)

메모리 DC & 비트맵을 메모리 DC 에 선택 ( 로드 )

 

윈도우즈는 비트맵을 곧바로 화면 DC 로 출력하는 함수는 제공하지 않는다.

비트맵을 출력하는 함수라면 아마 다음과 같은 형태를 상상할 수 있을 것이다.
 

OutBitmap ( hdc , x , y , "비트맵 열기" );   (존재하지 않는 함수)


이런 함수가 있으면 매우 좋겠지만 , 안타깝게도 이런 함수는 API 가 직접 지원하지 않는다.

왜냐하면 비트맵은 크기가 큰 데이터 덩어리 이며 , 따라서 출력 속도가 형편없이 느리고 화면으로 곧바로 출력할 경우 여러가지 꼴사나운 현상이 발생할 수 있기 때문이다.

마치 파일에서 한 바이트 단위로 읽어 들이는 함수가 없는 것과 같은 이유인데, 파일을 읽고 싶으면 반드시 열기 , 읽기 , 닫기 의 과정을 거쳐야 한다.

 

마찬가지로 비트맵도 워낙 대용량이라 직접 출력하는 함수는 제공하지 않으며 약간의 준비를 거친 후 출력해야 한다.

이렇게 준비 동작을 취한 후 출력하면 여러번 출력할 때 이미 준비된 데이터를 전송하기만 하면 되므로

출력속도가 빠르고 예비 동작을 미리 취해 놓을 수 있다는 점에서도 유리하다.

 

비트맵은 화면으로 직접 출력할 수 없으며 반드시 메모리 DC 에 미리 준비해 놓고 사용해야 한다.

메모리 DC 란 DC 와 동일한 특성을 가지며 ,그 내부에 출력 표면을 가진 메모리 영역이다.

메모리에 있기는 하지만 화면 DC 에서 사용할 수 있는 모든 출력을 메모리 DC 에서도 할 수 있다.

선 , 면 , 원 등의 작도 함수는 물론 화면 DC 에서는 불가능한 것까지도 가능하다.

그래서 메모리 DC 에 먼저 그림을 그린 후 사용자 눈에 그려지는 과정은 보여주지 않고

그 결과만 화면으로 고속 복사하는 방법 ( 더블 버퍼링 ) 을 많이 사용한다.

( 메모리 DC 에 먼저 그림을 그려둔다 -> 화면에 복사한다 )

 

사용자 눈에 화면이 그려지는 과정을 보여주는 것은 그리 깔끔한 모습이 아니다.

여기서 우리가 하고자 하는 비트맵 출력을 위해서도 반드시 메모리 DC 를 사용해야 한다.

비트맵도 일종의 GDI 오브젝트 이지만 화면 DC 에는 선택할 수 없으며 

메모리 DC 만이 비트맵을 선택할 수 있다.

그래서 메모리 DC 에 먼저 비트맵을 읽은 후 화면 DC 로 복사하는 것이다.

 


1.메모리DC 만들기
메모리 DC 를 만들 때는 다음 함수가 사용된다.
 

HDC CreateCompatibleDC( HDC hdc );                     // Compatible  : 호환이 되는

 

인수로 화면 DC 의 핸들을 주면 이 화면 DC 와 동일한 특성을 가지는 DC 를 메모리에 만들어 그 핸들을 리턴한다.

호환된다 라는 말은 사용하는 색상수 , 색상면 이 같다는 뜻이다.

호환되지 않는 DC 끼리는 정보를 공유할 수 없기 때문에 화면 DC 와 호환이 되는 메모리 DC 를 만들어야 한다.

즉 , 화면이 흑백이면 메모리 DC 도 흑백이어야 하고 , 화면이 256 색상이면 메모리 DC 도 256 색상으로 만들어져야 한다는 얘기다.


2. 비트맵 읽어들이기

메모리 DC 를 만든 후에는 비트맵을 읽어오고 이 비트맵을 메모리 DC 에 선택한다.

선택할 때는 여타의 GDI 오브젝트와 마찬가지로 SelectObject 함수를 사용하며 ( 펜 , 브러시등을 DC 에 적용하는 함수 )

비트맵을 읽어올 때는 LoadBitmap 함수를 사용한다.

 

HBITMAP LoadBitmap ( HINSTANCE hInstance , LPCTSTR lpBitmapName );

 

첫 번째 인수는 비트맵 리소스를 가진 인스턴스 핸들

두 번째 인수는 비트맵 리소스의 이름
 

읽어온 비트맵을 SelectObject 함수로 메모리 DC 에 선택하면 메모리 DC 의 표면에는 리소스에서 읽어온 비트맵이 그려져 있을 것이다.



3. 
메모리 DC 의 그림을 화면으로 복사 ( 빗블릿 )

이제 남은 일은 메모리 DC 에 그려진 비트맵을 화면으로 복사하는 것 뿐이다.

BitBlt ( 빗블릿 ) 함수는 DC 간의 영역끼리 고속 복사를 수행한다.

메모리 DC 의 표면에 그려져 있는 비트맵을 화면 DC로 복사 함으로써 비트맵을 화면으로 출력한다.

원형은 다음과 같다.

 

BOOL BitBlt ( HDC hdcDest , int nXDest, int nYDest , int nWidth , int nHeight, HDC hdcSrc , int nXSrc , int nYSrc ,                        DWORD dwRop );

 

첫 번째 인수는 복사 대상 DC ( 윈도우 DC ) 다음 네 개의 인수는 복사 대상 ( 윈도우 ) 의 XYWH  ( 어디에 출력할 것인지 ) hdcSrc 가 메모리 DC nXSrc , nYSrc 는 메모리 DC 상 의 좌표이되 BitBlt 은 비트맵의 크기를 변경하지 않고 복사를 수행 
폭과 높이는 복사 대상에서 한 번만 지정하고 복사원에서는 이 값을 그대로 사용한다.

소스를 보면 MemDC 의 0,0 위치를 복사 대상의 0,0 위치에 폭 123 , 높이 160 만큼 복사한다.

( 메모리 DC 의 그림의 50,50 위치부터 복사하고 싶다고 하면 이 값을 고치면 된다. )

그렇게 하면 다음과 같은 위치에서 부터 복사를 시작한다.

 
3-2)복사 옵션(빗블릿함수의 복사옵션)

BitBlt 의 마지막 인수 dwRop 는 래스터 연산 방법을 지정하며 , SRCCOPY 를 쓰면 메모리 DC 에 있는 그림을 그대로 복사한다.

dwRop 에 다른 값을 사용하면 ,기존 그림에 겹친다거나 반전 시킬 수도 있다.

앞에서 배운 그리기 모드와 개념적으로 유사하며 다음과 같은 기능이 있다.

 

 

   설명 
 BLACKNESS  대상 영역을 검정색으로 가득 채운다
 DSTINVERT  화면을 반전 시킨다
 MERGECOPY  소스 비트맵과 대상화면을 AND 연산 한다
 MERGEPAINT  소스 비트맵과 대상화면을 OR 연산 한다
 SRCCOPY  소스 영역을 대상 영역에 복사한다
 WHITENESS  대상 영역을 흰색으로 채운다

 

4. 
메모리 DC 해제 / 비트맵 해제

비트맵 출력이 끝난 후에는 비트맵 자체와 메모리 DC 를 해제해야 한다.

비트맵은 GDI 오브젝트 이므로 , DeleteObject 함수로 지우면 되고, 메모리 DC 는 DeleteDC 라는 별도의 함수를 사용하여 지운다. 비트맵을 지우기 전에 선택 해제를 먼저 해야 하므로 OldBitmap 변수가 필요하다

 






이 글을 공유하기

댓글

Designed by JB FACTORY