API 비트맵

IT/개발공부 / / 2020. 9. 15. 18:50
728x90
반응형

비트맵이란 이미지를 저장하고 있는 그래픽 오브젝트입니다. 미리 그려진 그림의 각 픽셀 색상과 기타 이미지의 크기, 해상도 등의 정보를 가지고 있는 이미지 데이터의 덩어리라고 할 수 있습니다.

 

DC간 고속 복사

DC 간의 영역끼리 이미지를 고속 복사 하는 긴으을 제공하는 API 함수가 있습니다.

Bit Block Transfer

우리가 모니터 화면에서 볼 수 있는 그림들은 결국 비디오 메모리에 있는 Bit들입니다. 결국 비디오 메모리를 하나의 커다란 비트맵으로 생각할 수 있습니다. 이때 아래 함수는 비디오 메모리의 특정 영역에 있는 Data를 다른 영역으로 옮길때 사용합니다.

BOOL BitBlt(HDC hdcDest, // handle to destination DC
            int nXDest, // x-coord of destination upper-left corner
            int nYDest, // y-coord of destination upper-left corner
            int nWidth, // width of destination rectangle 
            int nHeight, // height of destination rectangle
            HDC hdcSrc, // handle to source DC
            int nXSrc, // x-coordinate of source upper-left corner
            int nYSrc, // y-coordinate of source upper-left corner
            DWORD dwRop // raster operation code );

아래 예제는 배경화면을 나타내는 DC 에서 윈도우 ClientDC로 픽셀을 전송하는 예제입니다.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   PAINTSTRUCT ps;
   HDC hdcDisplay, hdcClient;
   static int cxClient, cyClient;
   switch( msg )
   {
      case WM_MOVE:
      InvalidateRect(hwnd, 0, TRUE);
      return 0;
      
      case WM_SIZE:
      cxClient = LOWORD(lParam);
      cyClient = HIWORD(lParam);
      return 0;
      
      case WM_ERASEBKGND:
      return TRUE;
      
      case WM_PAINT:
      hdcDisplay = CreateDC(TEXT("DISPLAY"), 0,0,0);
      hdcClient = BeginPaint( hwnd, &ps);
      BitBlt( hdcClient, 0, 0, cxClient, cyClient, hdcDisplay, 0, 0, SRCCOPY);
      DeleteDC( hdcDisplay );
      EndPaint( hwnd, &ps );
      return 0;
      
      case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   }
   return DefWindowProc( hwnd, msg, wParam, lParam);
}

BitBlt 함수에서 가장 중요한 점은 2개의 DC는 반드시 호환되어야 합니다.

 

StretchBlt

BitBlt() 함수는 크기를 늘이거나 줄일 수는 없습니다. 복사하면서 이미지의 크기를 늘리거나 줄이려는 경우는 아래의 함수를 사용해야 합니다.

BOOL StretchBlt( HDC hdcDest, // handle to destination DC
                 int nXOriginDest, // x-coord of destination upper-left corner
                 int nYOriginDest, // y-coord of destination upper-left corner
                 int nWidthDest, // width of destination rectangle
                 int nHeightDest, // height of destination rectangle
                 HDC hdcSrc, // handle to source DC
                 int nXOriginSrc, // x-coord of source upper-left corner
                 int nYOriginSrc, // y-coord of source upper-left corner
                 int nWidthSrc, // width of source rectangle
                 int nHeightSrc, // height of source rectangle
                 DWORD dwRop // raster operation code );

 

레스터 연산

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

 

비트맵 출력하기

윈도우즈가 지원하는 비트맵 포맷은 두 가지 종류가 있습니다.

 

첫 번째는 3.0 이전 버전에 사용하던 DDB(Device Dependent Bitmap)인데 이 비트맵은 출력 장치에 많이 의존되며 몇 가지 제한이 있습니다. DDB는 이미지의 크기와 색상에 관한 기본적인 정보와 그리고 이미지 데이터만으로 구성되어 있기 때문에 다양한 해상도의 장치에 광범위하게 사용되지 못하며 만들어진 장치 외의 다른 장치에서 출력하면 제대로 출력되지 못하는 경우가 있습니다.

 

두 번째는 DIB(Device Independent Bitmap) 입니다. 이름이 의미하는 대로 이 포멧의 비트맵은 장치에 독립적이기 때문에 어디서나 제 모양대로 출력될 수 있습니다. DIB는 DDB에 비해 색상 테이블과 해상도 정보 등의 추가 정보를 가지므로 장치에 종속되지 않으며 활용 용도가 훨씬 더 광범위하고 호환성이 뛰어납니다. 확장자 BMP를 가지는 비트맵 파일들은 모두 DIB 포맷으로 저장된 파일이며 리소스 에디터에서 만들어 주는 비트맵들도 모두 DIB입니다.

  • 하위 호환성을 위해 Win32 API는 여전히 DDB를 지원합니다. 따라서 DC에 선택될 수 있는 비트맵은 DDB 뿐입니다. DIB는 직접 DC에 선택될 수 없기 때문에 프로그램에서 곧바로 사용하기가 어렵습니다.
  • 리소스나 디렉토리에 있는 파일이미지는 DIB 포맷이고, LoadBitmap 함수나 LoadImage 함수를 사용하여 로드하면 DDB 포맷으로 자동 변환 됩니다.

LoadBitmap & LoadImage

윈도우즈 비트맵을 곧바로 화면 DC로 출력하는 함수는 제공하지 않습니다. 메모리 DC를 통해 먼저 출력한 후 고속복사하는 방법을 사용합니다.

 

메모리 DC란 화면 DC와 동일한 특성을 가지며 그 내부에 출력 표면을 가진 메모리 영역입니다. 메모리에 있기는 하지만 화면 DC에서 사용할 수 있는 모든 출력을 메모리 DC에서도 할 수 있습니다.

 

메모리 DC에 먼저 그림을 그린 후 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 고속복사 합니다.

메모리 DC를 만들 때는 아래 함수를 사용합니다.

HDC CreateCompatibleDC(HDC hdc);

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

 

비트맵을 읽어올 때는 아래 함수를 사용합니다.

HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);

첫 번째 인수는 비트맵 리소스를 가진 인스턴스의 핸들이며 두 번째 인수는 비트맵 리소스의 이름입니다. 읽어온 비트맵을 SelectObject 함수로 메모리 DC에 선택하면 메모리 DC의 표면에는 리소스에서 읽어온 비트맵이 그려집니다.

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기