티스토리 뷰

WinAPI

1) BitMap 파일구조

chrisysl 2018. 5. 8. 16:24

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

 · 파일헤드(BITMAPFILEHEADER)

 · 영상헤드(BITMAPINFOHEADER)

 · 팔레트정보(RGBQUAD)

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






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

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

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


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 로 복사하는 코드이다. 

이미지의 상하가 서로 반전되어 치환되고 있음을 알 수 있다. "rwsize"변수는 아래에서 설명한다.






영상 가로길이는 4바이트의 배수

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

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

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

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

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

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



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

호출시: int rwsize = WIDTHBYTES(biBitCount * biWidth);

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함