|
|

1. Information
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
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;
WIN32 API에서는 bitmap header부분을
파일정보와 비트맵정보로 구분해서 사용한다.
개인적으로 윈도우에서 작업을 하게 된다면 이 구조를 사용하지만
그렇지 않을 경우는 이 두부분을 한 구조체로 묶어서 사용한다.
|
bfType 2byte
bitmap file 식별자
반드시 "BM" 이여야 한다. 위의 구조체 타입으로 읽을 경우는 0x4D42(19778)이다.
(실제 파일상의 값은 0x42('B') 0x4D('M') byte_order가 small-endian 방식이다. Mac이나 Motorola처럼 big-endian에서는 다르게 표현 될려나? 확인 안해봐서 모르겠다. 이후 이 부분은 언급하지 않는다)
bfSize 4byte
file 전체의 크기를 나타낸다. ls나 dir혹은 탐색기의 등록정보를 이용하여 확인해 보면 동일하다.
bfReserved1 2byte
bfReserved2 2byte
그냥 예약 부분이다. 둘다 0으로 채워져야 한다.
굳이 예약부분을 2byte씩 둘로 나눈 이유가 무엇일까?
bfOffBits 4byte
BITMAPFILEHEADER 구조체로 부터 오프셋이란다.
괜히 MSDN 긁었나부다. 그냥 image data의 시작위치다.
biSize 4byte
구조체의 크기라고 써있다.
biSize부터 bitmap information에 대한 마지막 부분까지의 크기다.
WIN32 API에선 sizeof(BITMAPINFOHEADER)의 크기로 봐도 무방하다.
- 각각 자료형의 크기가 4byte라서(중간에 2byte는 2개) structure packed를 걱정할 필요는 없다.
biWidth 4byte
bitmap의 가로 pixel 크기이다.
biHeight 4byte
bitmap의 세로 pixel 크기이다.
양수/음수에 따라 bottom-up/top-down으로 나뉜다고 되어 있다.
뭐 일단 양수라고(bottom-up) 생각하고 넘어간다. 이 문제에 대해서 뒤에 이야기 한다.
biPlanes 2byte
해당 device에 대한 숫자라고 되어있다. 반드시 1이어야 한다
별로 의미가 없는 부분이다.
biBitCount 2byte
한 픽셀당 차지하는 비트수이다. 여기를 보면 이 비트맵이 몇 color인지(몇 bit인지) 알수 있다.
2에 대한 지수로 보면 간단하다.
1 - 2 color
4 - 16 color
8 - 256color
.
.
.
biCompression 4byte
압축 타입이라고 되어 있다.(top-down DIB에서는 사용 할 수 없다)
일반적으로 보통 0이지만 압축된 BMP의 경우에는 값이 세팅되어 있다.
wingdi.h 파일에서는 다음과 같이 선언되어 있다.
#define BI_RGB 0L
#define BI_REL8 1L
#define BI_RLE4 2L
pixel당 8bit 혹은 4bit로 Run_length 압축 됨
biSizeImage 4byte
압축되지 않은 이미지의 실제 크기이며 일반적으로 보통 0.
biSizeImage= biWidth * biHeight * 픽셀당_바이트수(256 color:1 byte, 24bit color:3 byte) 이지만
윈도우에서는 몇가지 이유로 4byte정렬을 하기 때문에 약간 보정을 해줘야 된다.
즉, biWidth가 4로 맞아 떨어지지 않는 경우에는 보정한다 - if (biWidth%4 != 0) ...
biHeight * (biWidth + biWidth%4) * 픽셀당_바이트수
biXPelsPerMeter 4byte
biYPelsPerMeter 4byte
출력 디바이스의 수평, 수직 해상도
biClrUsed 4byte
사용한 color
biClrImportant 4byte
중요한 color
2. Palette
biBitCount 값이 1 ~ 8 까지의 값일 경우에만 사용된다.
즉 8보다 큰 값이면 palette정보는 없다.
사용되는 색상이 2 ~ 256 color이면 색상을 사용하기 위해 색상 정보를 미리 정해 놓고
image data영역에서는 색상정보의 인덱스를(해당 color를 0부터 오름차순으로 번호를 매겨서) 이용하여
색상을 표시한다.

palette 크기는 bfOffBits에서 bitmap_information부분을 빼줘도 되지만
쉽게 생각해서 4 byte(RGB값과 dummy 1byte) * 색상갯수로 계산해도 된다.
1bit(2 color) 이미지라고 해서 꼭 흑백으로 표현되지는 않는다. palette 정보를 적,청 색으로 변경하면
얼마든지 다른색으로 표현할 수 도 있다.
여담으로 모든 이미지를 256 color로 작업할 경우
작은 이미지를(16*16정도나 그 보다 작을 경우) 표현하다 보면
실제 image data영역보다 header와 palette영역이 훨씬 큰 - 배보다 배꼽이 큰 경우도 발생한다.
3. Image data
말 그대로 image data영역이다.
biBitCount 값이 1 ~ 8일 경우에는 palette 색상의 index값을 가지며
해당 bit가 한 pixel을 나타낸다(8이면 2^8 즉, 1byte로 계산하며 그 이하는 비트로)
그 이상 color를 이용하면 image_data 영역에 직접 색상 정보를 기록한다.
그리고 한가지 주의 할 점이 보통의 경우 실제 이미지와 image_data 영역의 정보는 아래위가 바뀌어 있다.
실제 이미지가 △ 이런식으로 나타날 경우에는
image_data영역에는 ▽ 식으로 기록된다.
즉, 이미지의 하단 영역부터 한 라인식(pixel기준) 기록된다.

또 여담인데 실제로 많은 사람들이 다룰수 있는 포토샵으로 이미지 작업을 하다보면
가끔씩 실제 이미지가 △, image_data영역 △ 이런식으로 기록되는 경우가 많다.(요즘 버전은 안그럴려나?)
여지껏 디자이너와 작업을 할때 게임쪽 인력보다는 대부분 웹디자이너와 작업이였는데
역시 그들이 포토샵으로 이미지를 넘겨줘서 확인해 보고 뒤집힌 이미지가 나오면 그냥 그림판으로 다시 저장을 한번더 해주는...
이거 확인하는게 있었는데 어떤 필드 값인지 잘 기억이 안난다 - 나중에 기억나면 수정 할련다.
그리고 마지막으로 여담인데
그동안 주 타겟 os가 윈도우가 아니었던 관계로
윈도우 헤더파일 안 가져다 쓰고 bitmap 헤더 구조체를 작성해서 사용하여
파일에서 해당 크기 만큼 읽어 오다보면
꼭 2 byte씩 밀린다.
위에 윈도우 구조체 보면 맨 처음 식별자가 2byte이고 그 다음 부터는 잘도 4byte로 맞추어 놓음을 볼수 있다.
맨 처음 bitmap 작업 할때 structure_align을 안 겪어 봐서(그 전까지는 개념만 있었을 뿐...)
'Application Programming' 카테고리의 다른 글
쓰레드의 종류 (0) | 2014.11.25 |
---|---|
Bitmap 구조 1 (0) | 2010.01.18 |