Neoteny

반응형

 

비트맵 포맷의 구조


   BMP 파일포맷은 압축을 수행하지 않으며 헤드가 있는 여러 형식의 파일 중에서 구조가 가장 간단하다.



BITMAPFILEHEADER (파일 헤드)

BITMAPINFOHEADER (영상 헤드)

RGBQUAD                (팔레트 정보)


영상데이터 (거꾸로 들어있음)



비트맵 파일에 대한 정보 (파일헤드)


   "파일자체" 의 정보를 저장하고 있는 구조체로써 다음과 같이 미리 정의가 되어 있다.

 사용자는 단지 구조체 변수를 선언해서 사용만 하면 된다.

 

  1. typedef struct tagBITMAPFILEHEADER

    {

               WORD               bfType;                  // "BM" 이라는 값을 저장함

               DWORD             bfSize;                   // 바이트 단위로 전체파일 크기

               WORD               bfReserved1;          // 예약된 변수

               WORD               bfReserved2;          // 예약된 변수

               DWORD             bfOffBits;                // 영상데이터 위치까지의 거리

    } BITMAPFILEHEADER;


   오픈한 파일이 비트맵 파일인지 아닌지 확인하기 위한 변수가 bfType 이다.

 BMP 파일의 처음 두 바이트는 항상 "BM" 문자가 저장되어 있다.

 bfOffBits 는 파일 시작부분에서 실제 영상데이터가 존재하는 위치까지 바이트 단위의 거리를 나타낸다.

 오프셋 (offset) 이라고 한다.

 WORD 는 2바이트 (unsigned short), DWORD 는 4 바이트 (unsigned long) 변수를 나타낸다.



"영상 자체" 에 대한 정보 (영상헤드)


   비트맵 영상에 대한 크기나 흑백, 컬러 정보, 팔레트 크기 정보 등을 저장하기 위하여 파일헤드 바로 다음에 위치하는

 구조체 변수이다.

 

 


typedef struct tagBITMAPINFOHEADER

{

           DWORD              biSize;                       // 이 구조체의 크기

           LONG                biWidth;                      // 픽셀단위로 영상의 폭

           LONG                biHeight;                     // 영상의 높이

           WORD                biplanes;                    // 비트 플레인 수 (항상 1)

           WORD                biBitCount;                 // 픽셀당 비트수 (컬러, 흑백 구별)

           DWORD              biCompression;          // 압축유무

           DWORD              biSizeImage;              // 영상의 크기 (바이트 단위)

           LONG                biXPelsPerMeter;        // 가로 해상도

          LONG                biYPelsPerMeter;        // 세로 해상도

           DWORD              biClrUsed;                 // 실제 사용 색상 수

           DWORD              biClrImportant;            // 중요한 색상 인덱스

} BITMAPINFOHEADER;

  

   이 구조체에서 중요한 정보는

 영상화일의 크기를 나타내는 두 변수 biHeight 와 biWidth,

 흑백인지 컬러인지를 나타내는 biBitCount 변수,

 팔레트의 크기를 나타내는 biCirUsed 변수 등이다.

 biBitCount 변수가 8 이면 흑백영상이거나 2^8 = 256 개의 컬러수를 사용하는 컬러영상, 24 라면 트루컬러 영상,

16 이면 2^16 개의 컬러수를 사용하는 영상이다.



팔레트


   팔레트는 인덱스에 의한 컬러값을 저장하기 위한 구조체이다.

 이 구조체를 사용하여 팔레트의 수 만큼 배열을 할당하여 저장한다.

 256 컬러모드의 영상은 팔레트배열 크기가 256 개,

 16 비트 컬러 영상은 팔레트 크기가 2^16 개이다. biClrUsed 변수를 참조하면 된다.

 흑백영상의 경우 팔레트는 256 개이며,

 트루컬러의 경우는 인덱스 저장이 아니라 데이터값을 직접 저장하므로 팔레트가 없다.


typedef struct tagRGBQUAD

{

               BYTE          rgbBlue;                  // B 성분 (파란색)

               BYTE          rgbGreen;                // G 성분 (녹색)

               BYTE          rgbRed;                   // R 성분 (빨간색)

               BYTE          rgbReserved1;          // 예약된 변수

} RGBQUAD;



DIB 사용시 주의점


   실제로 비트맵 영상이 저장될 때는 이미지가 거꾸로 저장되어 있다. 따라서, 비트맵에서 영상데이터를 나중에

 영상처리를 위해 사용할 배열로 다시 저장할 때는 거꾸로 반전시켜 저장해주면 된다.


for (i = 0; i< biHeight; i++) {

    for (j = 0; j< biWidth; j++) {

        GrayImg[ i * biWidth + j ] = lpMem[ ( biHeight - i - 1 ) * rwsize + j ]

    }

}


   BMP 에서 읽어들인 영상버퍼 lpMem 에 있는 영상데이터를 나중에 사용할 임의의 배열 GrayImg 로 복사하는 코드이다.

 이미지의 상하가 서로 반전되어 치환되고 있음을 알 수 있다.



   비트맵은 메모리 저장시, 가로줄의 크기는 항상 4 바이트의 배수가 되어야 한다.

 실제 사용하는 영상의 가로길이는 4 바이트의 배수가 아닐 수 있으므로 이럴 경우는 4 의 배수바이트로 바꾸어 저장한다.

 예를 들어 지금 BMP 로 저장할 흑백영상 데이터의 실제 크기가 78 x 60 이라면 가로픽셀 78 은 78 byte 이고,

 4 의 배수가 아니므로 80 바이트로 만들고 나머지 두 바이트는 아무 값이나 넣어준다.

 실제 저장되는 메모리는 80 x 60 픽셀의 크기가 된다.


#define WIDTHBYTES(bits)    ((bits + 31) / 32 * 4)  // 4 바이트 배수로 변환


int rwsize = WIDTHBYTES(biBitCount * biWidth);


rwsize 변수는 BITMAPINFOHEADER 구조체의 biWidth 와 biBitCount 값을 사용하여 4 바이트의 배수로 만든다.

이 글은 스프링노트에서 작성되었습니다.

반응형