WINAPI - 비트맵 출력, 메모리 DC
내장형 하드웨어/WINAPI / 2011. 9. 15. 14:40
- 비트맵 출력
→ 복잡한 그림을 출력할 경우는 미리 그려진 비트맵을 사용한다.
→ 비트맵은 복잡한 그림을 출력하는 용도 외에도 화면의 일정영역을 복사해서 옮기기도 하고
→ 잠시 보관하기도 하며 화려한 애니메이션이 활용되기도한다.
- 비트맵 프로젝트 제작 과정
→ Bitmap 프로젝트를 만들고 실습용 비트맵 파일을 준비한다. 준비한 비트맵 파일을 Bitmap 프로젝트 디렉토리에 복사해 둔다.
→ 비트맵 리소스를 만든다. 프로젝트 디렉토리에 복사해둔 비트맵 파일을 Import한다.
→ Bitmap.rc 리소스 스크립트를 추가하고 팝업 메뉴에서 리소스 추가항목을 선택하여 리소스 타입을 선택한다.
→ Bitmap 타입에서 가져오기(Import)버튼을 눌러 준비해 두었던 비트맵 파일을 선택한다.
→ 이 비트맵을 IDB_BITMAP1이라는 ID로 임포트하며 리소스 스크립트에 이 비트맵이 추가된다.
→ 아래와 같이 코드를 수정한다.
- 메모리 DC
→ 윈도우즈는 비트맵을 곧바로 화면 DC로 출력하는 함수는 제공하지 않는다.
→ 왜냐하면 비트맵은 크기가 큰 데이터 덩어리이며 따라서 출력 속도가 형편없이 느리고 화면을 곧바로 출력할 경우 여러가지 문제가 발생할 수 있기 때문이다.
→ 마치 파일에서 한 바이트 단위로 읽어 들이는 함수가 없는 것과 같은 이유인데 파일을 읽고 싶으면 반드시 열기, 읽기, 닫기의 과정을 거쳐야 한다.
→ 마찬가지로 비트맵도 워낙 대용량이라 직접 출력하는 함수는 제공하지 않으며 약간이 준비를 거친 후 출력해야 한다.
→ 이렇게 준비 동작을 취한 후 출력하면 여러번 출력할 때 이미 준비된 데이터를 전송하기만 하면 되므로 출력 속도가 빠르고 예비 동작을 미리 취해 놓을 수 있다는 점에서도 유리하다.
→ 따라서, 비트맵은 화면으로 직접 출력할 수 없으며 반드시 메모리 DC에 미리 준비해 놓고 사용해야 한다.
→ 메모리 DC란 화면 DC와 동일한 특성을가지며 그 내부에 출력 표면을 가진 메모리 영역
→ 메모리에 있기는 하지만 화면 DC에서 사용할 수 있는 모든 출력을 메모리 DC에서도 할 수 있다.
→ 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 출력하는 방법(더블 버퍼링)을 많이 사용한다.
→ 메모리 DC를 만들 때는 다음 함수가 사용된다.
→ 선택할 때는 여타의 GDI 오브젝트와 마찬가지로 SelectObject 함수를 사용하며 비트맵을 읽어올 때는 LoadBitmap 함수를 사용한다.
→ 두 번재 인수는 비트맵 리소스의 이름
- BitBlt
→ BitBlt(빗블릿이라고 읽는다.) 함수는 DC간의 영역끼리 고속 복사를 수행한다.
→ 메모리 영역에 있응 비트맵을 화면 DC로 복사함으로써 비트맵을 화면으로 출력한다.
→ nXSrc, nYSrc,는 복사원의 좌표이며 BitBlt의 비트맵의 크기르 변경하지 않고 복사원에는 이 값을 그대로 사용한다.
→ BitBlt의 마지막 인수 dwRop는 래스터 연산 방법을 지정하며 SRCCOPY를 쓰면 복사원을 그대로 복사 대상으로 복사한다.
→ dwRop에 다른 값을 사용하면 기존 그림에 겹쳐진다거나 반전시킬 수도 있다.
→ 비트맵 크기를 자동으로 삽입하도록 바꾼 함수
- StetchBlt
→ DC간에 비트맵을 전송하는데 확대 및 축소가 가능하다는 점이 이전 함수와는 다르다.
→ 복잡한 그림을 출력할 경우는 미리 그려진 비트맵을 사용한다.
→ 비트맵은 복잡한 그림을 출력하는 용도 외에도 화면의 일정영역을 복사해서 옮기기도 하고
→ 잠시 보관하기도 하며 화려한 애니메이션이 활용되기도한다.
- 비트맵 프로젝트 제작 과정
→ Bitmap 프로젝트를 만들고 실습용 비트맵 파일을 준비한다. 준비한 비트맵 파일을 Bitmap 프로젝트 디렉토리에 복사해 둔다.
→ 비트맵 리소스를 만든다. 프로젝트 디렉토리에 복사해둔 비트맵 파일을 Import한다.
→ Bitmap.rc 리소스 스크립트를 추가하고 팝업 메뉴에서 리소스 추가항목을 선택하여 리소스 타입을 선택한다.
→ Bitmap 타입에서 가져오기(Import)버튼을 눌러 준비해 두었던 비트맵 파일을 선택한다.
→ 이 비트맵을 IDB_BITMAP1이라는 ID로 임포트하며 리소스 스크립트에 이 비트맵이 추가된다.
→ 아래와 같이 코드를 수정한다.
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc, MemDC;
PAINTSTRUCT ps;
HBITMAP MyBitmap, OldBitmap;
hdc = BeginPaint(hWnd, &ps);
MemDC = CreateCompatibleDC(hdc); // 메모리 DC를 가져온다.
MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));//비트맵 리소스를 받아온다.
OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap); //메모리DC에 비트맵오브젝트를 넣는다.
BitBlt(hdc, 0, 0, 740, 416, MemDC, 0, 0, SRCCOPY); // DC로 복사(SRCCOPY)한다.
SelectObject(MemDC, OldBitmap);
DeleteObject(MyBitmap); // 비트맵은 GDI 오브젝트이므로 DeleteObject로 지운다.
DeleteDC(MemDC); // 메모리 DC를 지운다.
EndPaint(hWnd, &ps);
return 0;
}
{
HDC hdc, MemDC;
PAINTSTRUCT ps;
HBITMAP MyBitmap, OldBitmap;
hdc = BeginPaint(hWnd, &ps);
MemDC = CreateCompatibleDC(hdc); // 메모리 DC를 가져온다.
MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));//비트맵 리소스를 받아온다.
OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap); //메모리DC에 비트맵오브젝트를 넣는다.
BitBlt(hdc, 0, 0, 740, 416, MemDC, 0, 0, SRCCOPY); // DC로 복사(SRCCOPY)한다.
SelectObject(MemDC, OldBitmap);
DeleteObject(MyBitmap); // 비트맵은 GDI 오브젝트이므로 DeleteObject로 지운다.
DeleteDC(MemDC); // 메모리 DC를 지운다.
EndPaint(hWnd, &ps);
return 0;
}
→ 출력 결과
- 메모리 DC
→ 윈도우즈는 비트맵을 곧바로 화면 DC로 출력하는 함수는 제공하지 않는다.
→ 왜냐하면 비트맵은 크기가 큰 데이터 덩어리이며 따라서 출력 속도가 형편없이 느리고 화면을 곧바로 출력할 경우 여러가지 문제가 발생할 수 있기 때문이다.
→ 마치 파일에서 한 바이트 단위로 읽어 들이는 함수가 없는 것과 같은 이유인데 파일을 읽고 싶으면 반드시 열기, 읽기, 닫기의 과정을 거쳐야 한다.
→ 마찬가지로 비트맵도 워낙 대용량이라 직접 출력하는 함수는 제공하지 않으며 약간이 준비를 거친 후 출력해야 한다.
→ 이렇게 준비 동작을 취한 후 출력하면 여러번 출력할 때 이미 준비된 데이터를 전송하기만 하면 되므로 출력 속도가 빠르고 예비 동작을 미리 취해 놓을 수 있다는 점에서도 유리하다.
→ 따라서, 비트맵은 화면으로 직접 출력할 수 없으며 반드시 메모리 DC에 미리 준비해 놓고 사용해야 한다.
→ 메모리 DC란 화면 DC와 동일한 특성을가지며 그 내부에 출력 표면을 가진 메모리 영역
→ 메모리에 있기는 하지만 화면 DC에서 사용할 수 있는 모든 출력을 메모리 DC에서도 할 수 있다.
→ 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 출력하는 방법(더블 버퍼링)을 많이 사용한다.
→ 메모리 DC를 만들 때는 다음 함수가 사용된다.
HDC CreateCompatibleDC(HDC hdc);
→ 인수로 화면 DC의 핸들을 주면 이 화면 DC와 동일한 특성을 가지는 DC를 메모리에 만들어 핸들을 리턴한다.→ 선택할 때는 여타의 GDI 오브젝트와 마찬가지로 SelectObject 함수를 사용하며 비트맵을 읽어올 때는 LoadBitmap 함수를 사용한다.
HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);
→ 첫 번째 인수는 비트맵 리소스를 가진 인스턴스의 핸들→ 두 번재 인수는 비트맵 리소스의 이름
- BitBlt
→ BitBlt(빗블릿이라고 읽는다.) 함수는 DC간의 영역끼리 고속 복사를 수행한다.
→ 메모리 영역에 있응 비트맵을 화면 DC로 복사함으로써 비트맵을 화면으로 출력한다.
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);
→ 첫 번째 인수는 복사 대상 DC이며 다음 네개의 인수는 복사 대상의 XYWH이며 hdcSrc가 복사원의 DC이다.→ nXSrc, nYSrc,는 복사원의 좌표이며 BitBlt의 비트맵의 크기르 변경하지 않고 복사원에는 이 값을 그대로 사용한다.
→ BitBlt의 마지막 인수 dwRop는 래스터 연산 방법을 지정하며 SRCCOPY를 쓰면 복사원을 그대로 복사 대상으로 복사한다.
→ dwRop에 다른 값을 사용하면 기존 그림에 겹쳐진다거나 반전시킬 수도 있다.
→ 비트맵 크기를 자동으로 삽입하도록 바꾼 함수
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc, MemDC;
PAINTSTRUCT ps;
HBITMAP MyBitmap, OldBitmap;
// add
BITMAP bit;
int x, y;
hdc = BeginPaint(hWnd, &ps);
MemDC = CreateCompatibleDC(hdc);
MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap);
// add
GetObject(MyBitmap, sizeof(BITMAP), &bit);
x = bit.bmWidth;
y = bit.bmHeight;
BitBlt(hdc, 0, 0, x, y, MemDC, 0, 0, SRCCOPY);
SelectObject(MemDC, OldBitmap);
DeleteObject(MyBitmap);
DeleteDC(MemDC);
EndPaint(hWnd, &ps);
return 0;
}
{
HDC hdc, MemDC;
PAINTSTRUCT ps;
HBITMAP MyBitmap, OldBitmap;
// add
BITMAP bit;
int x, y;
hdc = BeginPaint(hWnd, &ps);
MemDC = CreateCompatibleDC(hdc);
MyBitmap = LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1));
OldBitmap = (HBITMAP)SelectObject(MemDC, MyBitmap);
// add
GetObject(MyBitmap, sizeof(BITMAP), &bit);
x = bit.bmWidth;
y = bit.bmHeight;
BitBlt(hdc, 0, 0, x, y, MemDC, 0, 0, SRCCOPY);
SelectObject(MemDC, OldBitmap);
DeleteObject(MyBitmap);
DeleteDC(MemDC);
EndPaint(hWnd, &ps);
return 0;
}
- StetchBlt
→ DC간에 비트맵을 전송하는데 확대 및 축소가 가능하다는 점이 이전 함수와는 다르다.
BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc. DWORD dwRop);
'내장형 하드웨어 > WINAPI' 카테고리의 다른 글
WINAPI - 컨트롤(버튼) (0) | 2011.09.19 |
---|---|
WINAPI - Font (0) | 2011.09.16 |
WINAPI - RopMode2 실습 (0) | 2011.09.09 |
WINAPI - 그리기 모드 (0) | 2011.09.09 |
WINAPI - 그래픽(색상) (0) | 2011.09.08 |