본문 바로가기

무작정 따라해보기(정리, 문제풀기)/Win32API

17. [WIN32API 프로그래밍] GDI오브젝트와 메모리DC를 이용하여 비트맵 이미지 출력하기

728x90

 

'나우캠퍼스X아워즈팜'유튜브의 'Win32 API 5강. 그래픽 오브젝트 (2/2)'영상을 보고 정리한 내용입니다.

 

비트맵(Bitmap) 파일 확장자는 이미지의 가장 기본이 되는 형식이며 비트맵 확장자로 이미지를 저장하고 불러올 수 있습니다.

 

이미지는 색상에 대한 정보가 데이터파일로 저장되어있는 것이고 그 대부분 데이터를 읽어서 메모리에 보낸 다음 출력을 합니다.

 

이미지 형식 종류

  • bmp, jpg, gif, tga 등
  • bmp는 압축 x.
  • jpg는 압축을 하며 jpg 관련 라이브러리를 링크해서 함수를 사용하여 쓸 수 있다.
  • tga는 게임에서 많이 쓰인다.

 

비트맵을 다루는 두 가지 방법

  • 비트맵을 리소스에 등록하여 사용(비쥬얼 스튜디오에 넣어서 사용. LoadBitmap()함수 사용)
  • LoadImage()함수를 이용(원하는 파일을 해당하는 경로에서 읽어냄)

 

BitBlt() 함수

  • BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, DWORD dwRop);
  • hdcDest는 출력하고자하는 화면의 dc
  • nXDest, nYDest는 그릴 x, y 좌표
  • nWidth, nHeight는 이미지 가로세로길이
  • hdcSrc는 화면 DC에 출력할 메모리DC.
  • nXSrc, nYSrc는 메모리DC의 어느 시작점부터 출력할 것인지. (이미지의 어느 위치부터 시작하여 출력할 것인지라고 생각)
  • dwRop은 메모리DC(이미지)를 변경할 수 있는 부분이며 그냥 그대로 출력할 것이라면 SRCCOPY를 사용한다.
  • 위와 같은 정보들을 통하여 메모리DC에 올라와 있는 이미지를 화면DC에 출력한다.
  • 이미지 데이터는 이미지에 대한 정보를 가지고 있다. 이미지 데이터는 헤더정보와 실제 데이터 정보를 가지고 있는데 헤더정보 안에 있는 정보를 통하여 실제 데이터 정보(이미지)를 다룰 수 있다. 헤더정보에는 가로, 세로 정보 등이 있고 이미지의 헤더 정보를 알려주는 함수가 있기 때문에 nWidth, nHeight는 이미지의 헤더 정보를 가져오는 함수를 통하여 얻을 수 있다.(GetObject()함수)

 

GetObject() 함수

  • GetObject() 함수를 이용하여 비트맵에 대한 정보를 얻어올 수 있다.
  • int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
  • hgdiobj는 비트맵 핸들
  • cbBuffer는 읽고자 하는 오브젝트의 메모리 사이즈(이미지 정보를 담을 구조체의 사이즈)
  • lpvObject는 헤더정보를 가지고자 하는 구조체 변수의 메모리
  • cbBuffer사이즈만큼 hgdiobj의 헤더 정보를 lpvObject에 저장해준다.

 

메모리DC

  • 화면 DC와 동일한 특성을 가진 DC이다.
  • 이미지의 정보를 메모리에 올려야 화면에 이미지를 출력할 수 있는데 메모리DC는 화면과 호환되는 이미지의 메모리의 정보를 가지고 있다.
  • CreateCompatibleDC(HDC hdc) 함수 이용하여 화면과 호환되는 메모리 DC를 얻는다.
  • hdc는 현재 화면 DC. GetDC()로 얻거나, WM_PAINT메시지가 발생하였을 때에는 BeginPaint()로 얻는다.

 

BITMAP 구조체

  • typedef struct tagBITMAP {        int bmType;
            int bmWidth;
            int bmHeight;
            int bmWidthBytes;
            BYTE bmPlanes;
            BYTE bmBitsPixel;
            LPVOID bmBits;
    } BITMAP;
  • GetObject()함수를 이용하여 이 구조체에 그 비트맵에 대한 헤더 정보를 저장하면 이미지의 가로(bmWidth), 세로(bmHeight) 길이 등을 얻을 수 있다.

 

비트맵을 출력하는 순서

  1. 비트맵의 핸들 얻기 ( LoadBitmap(), LoadImage() )
  2. 메모리 DC 생성 ( CreateCompatibleDC() ) --> 이미지를 로드 했으니 메모리DC를 만들기 )
  3. SelectObject()로 CreateCompatibleDC() 함수로 생성한 메모리DC와 비트맵의 핸들을 넘겨주어서 그 메모리DC에서 이 비트맵을 사용하겠다고 지정하기
  4. BitBlt()함수로 비트맵 출력하기(위에서 만든 메모리DC, 이미지 크기, 위치, 출력할 위치 등을 넘겨줌)
  5. 비트맵 핸들 해제 --> BOOL DeleteObject(HGDIOBJ hObject);
    메모리 DC 해제 --> BOOL DeleteDC(HDC hdc);

 

비트맵을 확대, 축소 하는 함수

StretchBlt()

  • BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);
  • hdcDest: 출력하고자 하는 화면 dc
  • nXOriginDest, nYOriginDest: 출력할 x, y 좌표값
  • nWidthDest, nHeightDest: 이미지의 확대 또는 축소를 할 넓이
  • hdcSrc: 이미지의 메모리DC
  • nXOriginSrc, nYOriginSrc: 이미지의 시작할 부분의 좌표
  • nWidthSrc, nHeightSrc: 이미지의 넓이
  • dwRop은 메모리DC(이미지)를 변경할 수 있는 부분이며 그냥 그대로 출력할 것이라면 SRCCOPY를 사용

TransparentBlt()

  • 확대와 축소 + 특정색을 제외한 나머지의 색상만 확대 또는 축소를 할 수 있는 함수.
  • msimg32.lib 라이브러리를 추가해야 사용할 수 있다.(링커에 추가만 해주면 됨)
  • BOOL TransparentBlt( HDC hdcDest, int xoriginDest, int yoriginDest, int wDest, int hDest, HDC hdcSrc, int xoriginSrc, int yoriginSrc, int wSrc, int hSrc, UINT crTransparent);
  • crTransparent는 GetPixel()함수로 특정 좌표의 색상값을 알아내거나 RGB()함수로 RGB값을 지정해주어서 그 특정 색을 제외하고 나머지에게만 확대 또는 축소를 적용할 수 있다.

 

오류가 있다면 댓글로 알려주시면 감사하겠습니다. ^^