본문 바로가기

devlog/Windows API

Bitmap Format DIB DDB 차이 정리

* win32 api를 사용해서 개발 중에 DIB와 DDB의 차이점을 알아보다가 이 기회에 정리해서 헷갈릴 때 다시 보도록 한다.

* win32 api를 기준으로 알아본 자료이며, 리눅스나 기타 다른 OS에서도 동일하게 적용된다는 것은 보장할 수 없다.




1. DDB(Device Dependent Bitmap)

2. DIB(Device Independent Bitmap)



  • DDB의 특징
    1. 윈도우즈 3.0 이전 버전에서 사용. (내가 태어나기도 전인 1990.05.22 발매된 윈도우 :-0 )
    2. 출력 장치에 의존적 => 컬러비트맵인 경우 흑백만 지원하는 디바이스에서 출력할 수 없음.
    3. 구조 => 이미지의 크기, 색상, 이미지 데이터만으로 구성됨.
    4. 다양한 해상도의 장치에 사용되지 못함.


  • DIB의 특징
    1. OS/2 2.0의 프레젠테이션 매니져에서 처음 소개된 비트맵. 윈도우즈 3.0버전부터 지원시작.
    2. 출력 장치에 독립적 => 색상 테이블, 해상도 정보 등의 추가 정보를 가지므로 장치에 종속되지 않음.
    3. 장치에 독립적이기 때문에 활용도가 넓고 호환성이 뛰어남.
        => 컬러 비트맵을 흑백장치에서 출력가능.



  • DIB가 장치에 독립적이라 훨씬 유리하다면 일관성있게 DIB 하나만하면 안되나?
    1. 이전 윈도우 하위 호환성을 위해 DDB를 지원해야함. 또한 지금까지 많이 사용되므로 없앨수가 없음.
    2.
    DC에 선택될 수 있는 비트맵은 오직 DDB뿐.
        => DC의 색상 포맷이 고정되어 있으므로 DIB는 직접 DC에 선택될 수 없고,
             DIB또한 DDB로 변환해야 출력가능해진다. 

    3. 프로그램 내부에서 만들어지고 파괴되는 비트맵은 DDB가 훨씬 더 효율적



  • Win32에서 DDB의 사용
    1. HBITMAP으로 지칭되는 비트맵 오브젝트는 DDB를 말함.
    2.리소스 에디터에 의해 만들어지는 비트맵 리소스들은 모두 DIB임.
        => 그러나 이 리소스는 LoadBitmap 함수에 의해 읽혀지면서 현재 비디오 모드와 호환되는 DDB로 변경됨.
  • DDB Syntax
    typedef strcut tagBITMAP{
         LONG bmType;
         LONG bmWidth;
         LONG bmHeight;
         LONG bmWidthBytes;
         WORD bmPlanes;
         WORD bmBitsPixel;
         LPVOID bmBits;
    }BITMAP;
    LONG bmType : 비트맵의 타입을 지정함. 논리적 비트맵의 경우 이 값은 0이어야 함.
    LONG bmWidth : 비트맵의 넓이. 0보다 커야함 (픽셀 단위)
    LONG bmHeight : 비트맵의 높이. 0보다 커야함 (픽셀 단위)
    LONG bmWidthBytes : 스캔라인 한 줄의 바이트 수.
                                  비트값이 WORD(x86-32bit)정렬된 배열을 만든다고 가정하기 때문에 반드시 2로 나눠져야 함.
    WORD bmPlanes : 컬러 평면의 수
    WORD bmBitsPixel : 한 픽셀을 표현하기 위해 필요한 비트수
                                1 : 흑백 
                                4 : 16색
                                8 : 256색
                                24 : 트루컬러 비트맵
    LPVOID bmBits : 비트맵의 실제 데이터, 비트 값의 위치에 대한 포인터
                            => ex) 0xe4, 0xc2 ...


  • DDB 생성
    DDB 비트맵을 만드는 함수.
    HBITMAP CreateBitmap( int nWidth, int nHeight, UINT cPlanes, UINT cBitsPerPel, CONST VOID* lpvBits );
    HBITMAP CreateBitmapIndirect( CONST BITMAP*lpbm );

    CreateBitmap 함수로 컬러 비트맵을 만드는 것도 가능은 하지만 컬러 비트맵은 흑백보다 비트맵 데이터가 복잡하여 수작업으로 만들기가 어려울 뿐만 아니라 컬러 비트맵은 반드시 현재 화면의 색상 포맷과 호환되어야만 출력할 수 있으므로 임의의 색상수로 비트맵을 만들어서는 안되며, 반드시 GetDeviceCaps()로 색상면수와 픽셀당 비트수를 조사하여 호환 비트맵을 만들어야함. 
    이 작업을 대신해주는 함수는 

    HBITMAP CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight );
    이 함수는 hdc와 호환되는 포맷의 비트맵을 nWidth, nHeight 크기로 만듬.
    여기서 "호환된다"는 말은 색상 포맷(
    색상면, 픽셀당 비트수)이 같다는 뜻.
    이 함수는 비트맵을 만들기만 하며 래스터 데이터는 초기화하지 않으므로 내부 표면에 그림은 아직 없는 상태.


  • DIB 구조
    DIB는 다양한 장치에 사용하기 위해 비트맵 출력에 대한 상세 정보를 포함하고 있음
    고수준 라이브러리를 쓸 계획이라면 몰라도 상관 없으나 비트맵을 제대로 활용해 보고 그래픽 파일의 구조에
    대해 깊이 있게 탐구해 보고 싶다면 DIB의 구조를 익혀야 함.

  • Bitmap Storage (MSDN)
  • BITMAPFILEHEADER

     BITMAPINFOHEADER

     RGBQUAD array (color table)

     Color-index array

  • BITMAPFILEHEADER 구조체
    DIB를 포함하는 파일의 종류, 크기, 레이아웃에 대한 정보를 포함.
    typedef struct tagBITMAPFILEHEADER {
            WORD    bfType;
            DWORD   bfSize;
            WORD    bfReserved1;
            WORD    bfReserved2;
            DWORD   bfOffBits;
    } BITMAPFILEHEADER;

    bfType : 파일의 형태를 지정하는 매직 넘버이며 반드시 'B' 'M'이어야함.(0x42, 0x4d)
    bfSize : 비트맵 파일의 크기를 바이트 단위로 지정
    bfReserved1 : 예약. 0으로 설정
    bfReserved2 : 예약. 0으로 설정
    bfOffBits : BITMAPFILEHEADER 구조체의 비트맵 비트의 시작으로부터 실제 데이터까지의 오프셋 바이트.
                  비트맵 전체 중 이 오프셋부터 실제 데이터


    이 구조체는 DIB가 디스크의 파일로 저장될 때만 사용되며 비트맵을 출력할 때는 사용되지 않음.
    => 파일로 저장된 BMP파일에만 이 구조체가 있고 메모리에 올라간 DIB에는 이 구조체가 없음.

  • BITMAPINFOHEADER 구조체
    BITMAPFILEHEADER 구조체 뒤에 오는 구조체.
    DIB의 크기와 색상 포맷에 관한 정보, 기타 장치 독립성을 보장하는 몇 가지 정보들을 가지는 구조체.
    typedef struct tagBITMAPINFOHEADER{
            DWORD      biSize;
            LONG       biWidth;
            LONG       biHeight;
            WORD       biPlanes;
            WORD       biBitCount;
            DWORD      biCompression;
            DWORD      biSizeImage;
            LONG       biXPelsPerMeter;
            LONG       biYPelsPerMeter;
            DWORD      biClrUsed;
            DWORD      biClrImportant;
    } BITMAPINFOHEADER;





우선 BITMAPINFOHEADER까지만 정리하고 나머지 두개는 이어서 정리하겠다.