Win32 API with 나우캠퍼스

Win32 API 5강. 그래픽 오브젝트(2) 비트맵

코다람쥐 2022. 8. 15. 23:41

5. 비트맵

개요


이미지 종류

bmp, jpg, gif, tga 등

 

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

1) 비트맵을 리소스에 등록하여 사용

장점 : 프로그래밍이 쉽다

단점 : 비트맵이 많아질수록 프로그램의 용량이 커진다

 

2) LoadImage() 함수를 이용하여 파일로부터 읽어내는 방법

장점 : 경로를 통해서 이미지를 읽어낼 수 있다.(많이 사용)

단점 : 프로그래밍이 어렵다

 

▩ 비트맵을 읽어 출력하는 순서

1) 비트맵의 핸들을 얻는다 : LoadBitmap(), LoadImage()

2) 메모리 DC 생성 :  CreateCompatibleDC()

3) 메모리 DC에 비트맵 적용 : SelectObject()

4) 비트맵 출력 : BitBlt()

5) 메모리 dc와 비트맵 제거 : DeleteDC(), DeleteObject()

 

비트맵 읽기


목적 : 비트맵의 핸들을 얻기 위함.

 

▩ LoadBitmap()

HBITMAP LoadBitmapA(
  [in] HINSTANCE hInstance,
  [in] LPCSTR    lpBitmapName
);

hInstance : 사용할 윈도우 핸들

lpBitmapName : 리소스에 등록된 사용할 파일 이름. MAKEINTRESOURCE() 함수활용

 

▩ LoadImage()

HANDLE LoadImageA(
  [in, optional] HINSTANCE hInst,
  [in]           LPCSTR    name,
  [in]           UINT      type,
  [in]           int       cx,
  [in]           int       cy,
  [in]           UINT      fuLoad
);

hInst  : 0(자기 자신의 인스턴스 사용)

name : 파일 경로

type : 이미지 타입 입력( ex - IMAGE_BITMAP )

cx : 이미지 크기 x축. NULL을 넣으면 원본크기

cy : 이미지 크기 y축 . NULL을 얺으면 원본크기

fuLoad : 하단 'fuLoad 설정' 참조.

 

▩ fuLoad 설정

1) 실제 이미지 크기 입력을 할 때

LR_CREATEDIBSECTION | LR_LOADFROMFILE

 

 

2) 0 또는 LR_DEFAULTSIZE로 입력할 때

LR_CREATEDIBSECTION | LR_LOADFROMFILE | LR_DEFAULTSIZE

 

fuLoad의 자세한 내용은 MSDN문서 참조

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-loadimagew

 

LoadImageW function (winuser.h) - Win32 apps

Loads an icon, cursor, animated cursor, or bitmap. (Unicode)

docs.microsoft.com

 

▩ 핸들 형변환

HANDLE => HBITMAP

(HBITMAP)LoadImage( ... )

 

메모리 DC


▩ 화면과 동일한 특성을 가진 메모리 일부

▩ 호환되는 메모리 DC 생성 함수

HDC CreateCompatibleDC(HDC hdc);

hdc : 사용할 DC

 

 

메모리 DC에 비트맵 복사 및 출력


▩ SelectObject()

HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);

hdc : 사용할 메모리 DC

hgdiobj : 사용할 GDI오브젝트

 

▩ 비트맵 출력

BOOL BitBlt(
  [in] HDC   hdc,
  [in] int   x,
  [in] int   y,
  [in] int   cx,
  [in] int   cy,
  [in] HDC   hdcSrc,
  [in] int   x1,
  [in] int   y1,
  [in] DWORD rop
);

hdc : 사용할 DC

x : 그려질 그림에 대한 x좌표 위치

y : 그려질 그림에 대한 y좌표 위치

cx : 이미지 가로길이( 하단의 BITMAP 구조체의 정보를 이용해서 가로길이 추출 - bmWidth)

cy : 이미지 세로길이( 하단의 BITMAP 구조체의 정보를 이용해서 세로길이 추출 - bmHeight)

hdcSrc : 메모리 DC

x1 : 메모리 DC x크기(0을 입력하면 원본크기)

y1 : 메모리 DC y크기(0을 입력하면 원본크기)

rop : SRCCOPY(원판 자체를 화면에 출력) 입력

 

▩ BITMAP 구조체

typedef struct tagBITMAP { /* bm*/
    int bmType;
    int bmWidth; // 이미지 가로길이
    int bmHeight; // 이미지 세로길이
    int bmWidthBytes;
    BYTE bmPlanes;
    BYTE bmBitsPixel;
    LPVOID bmBits;
}BITMAP;

 

 

▩ GetObject()

int GetObject(
  [in]  HANDLE h,
  [in]  int    c,
  [out] LPVOID pv
);

h : 얻고자 하는 비트맵 핸들

c : 읽고자하는 비트맵 오브젝트의 헤더정보에 대한 메모리 사이즈. ex - sizeof(BITMAP) 입력

pv : 얻고자하는 비트맵 구조체 변수의 메모리 주소

 

비트맵과 메모리DC 제거


▩ 비트맵 제거

BOOL DeleteObject(HGDIOBJ hObject);

hObject : 제거하고자 하는 오브젝트

 

▩ 메모리 DC 제거

BOOL DeleteDC(HDC hdc);

hdc : 제거하고자 하는 메모리 DC

 

사용예시.

            hBitmap = (HBITMAP)LoadImage(0, strFile, IMAGE_BITMAP,
            	NULL, NULL, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
            hdcMem = CreateCompatibleDC(hdc);
            SelectObject(hdcMem, hBitmap);
            GetObject(hBitmap, sizeof(BITMAP), &bm);
            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
            DeleteObject(hBitmap);
            DeleteDC(hdcMem);

 

 

비트맵 확대축소 출력 함수


 

▩ StretchBlt() : 확대축소

BOOL StretchBlt(
  [in] HDC   hdcDest,
  [in] int   xDest,
  [in] int   yDest,
  [in] int   wDest,
  [in] int   hDest,
  [in] HDC   hdcSrc,
  [in] int   xSrc,
  [in] int   ySrc,
  [in] int   wSrc,
  [in] int   hSrc,
  [in] DWORD rop
);

hdcDest : 출력하고자하는 DC

xDest : 출력하고자 하는 x의 값

yDest : 출력하고자 하는 y의 값

wDest : 가로길이 확대비율 

hDest : 세로길이 확대비율 

hdcSrc : 

xSrc : 

ySrc :  

wSrc : 

hSrc : 

rop : SRCCOPY

 

▩ TransparentBlt() : 확대축소 + 특정색 제외하고 출력

프로젝트(P) => 속성 => 링커 => 입력 => 추가종속성 => 편집 => 'msimg32.lib' 입력 => 확인

BOOL TransparentBlt(
  [in] HDC  hdcDest,
  [in] int  xoriginDest,
  [in] int  yoriginDest,
  [in] int  wDest,
  [in] int  hDest,
  [in] HDC  hdcSrc,
  [in] int  xoriginSrc,
  [in] int  yoriginSrc,
  [in] int  wSrc,
  [in] int  hSrc,
  [in] UINT crTransparent
);

hdcDest : 

xoriginDest : 

yoriginDest : 

wDest : 

hDest : 

hdcSrc : 

xoriginSrc : 

yoriginSrc : 

wSrc : 

hSrc : 

crTransparent : GetPixel()함수 또는 RGB()함수 이용.