'비트맵'에 해당되는 글 2건

  1. 2010.01.18 Bitmap 구조 2
  2. 2010.01.18 Bitmap 구조 1




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부분을
파일정보와 비트맵정보로 구분해서 사용한다.

개인적으로 윈도우에서 작업을 하게 된다면 이 구조를 사용하지만
그렇지 않을 경우는 이 두부분을 한 구조체로 묶어서 사용한다.

Offset Hexa Size Name Contents
0 0x00 2 bfType Specifies the file type. It must be BM
2 0x02 4 bfSize Specifies the size, in bytes, of the bitmap file .
6 0x06 2 bfReserved1 Reserved; set to zero
8 0x08 2 bfReserved2 Reserved; set to zero
10 0x0A 4 bfOffBits Specifies the offset, in bytes, from the BITMAPFILEHEADER structure to the bitmap bits
14 0x0E 4 biSize Specifies the number of bytes required by the structure.
18 0x12 4 biWidth Specifies the width of the bitmap, in pixels.
22 0x16 4 biHeight specifies the height of the image, in pixels.If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed. 
26 0x1A 2 biPlanes Specifies the number of planes for the target device. This value must be set to 1.
28 0x1C 2 biBitCount Specifies the number of bits per pixel. The biBitCount member of the BITMAPINFOHEADER structure determines the number of bits that define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values.
30 0x1E 4 biCompression Specifies the type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed). This member can be the one of the following values:
34 0x22 4 biSizeImage Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.
38 0x26 4 biXPelsPerMeter Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap. An application can use this value to select a bitmap from a resource group that best matches the characteristics of the current device.
42 0x2A 4 biYPelsPerMeter Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap
46 0x2E 4 biClrUsed Specifies the number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression. If biClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed member specifies the actual number of colors the graphics engine or device driver accesses. If biBitCount is 16 or greater, the biClrUsed member specifies the size of the color table used to optimize performance of the system color palettes. If biBitCount equals 16 or 32, the optimal color palette starts immediately following the three DWORD masks.
50 0x32 4 biClrImportant Specifies the number of color indexes required for displaying the bitmap. If this value is zero, all colors are required.


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
Posted by Finebe
,




비트맵 구조는 의외로 단순하다.
일단 비트맵에 대한 크기등의 정보와 실제 데이터로 나뉜다. (하긴 다른 파일들도 정보와 데이터로 나뉘겠지만)

다 알고 있는데로 비트맵은 이미지의 하나하나의 픽셀에 대한 색깔 정보를 가지고 있는 구조다.
그래서 다른 이미지 포맷에(jpeg, gif등) 비해 상당히 파일크기가 큰 편이다.

1. information
비트맵 식별자, 가로/세로 사이즈, 파일크기, 사용할 색상수, 데이터 시작위치등이 포함되어 있다.
주의할 점은 사용할 색상수(흔히들 말하는 흑백, 16 color, 256 color등)를 표현하는 것으로
2의 지수형태중 지수만 표현하고 있다.
ex) 16color = 2^4,  256color = 2^8

2. palette
사용할 색상을 하나씩 지정한다.
16color 라면 16가지 색깔을 하나의 색상당 RGB형태로 4byte표기한다
(Red:0~255, Green:0~255, Blue:0~255, dummy 1byte-대부분 0값이다)
결국 4byte * 16(16가지 색상) 만큼의 크기를 차지한다.
RGB값만 표현하면 3byte면 되지만 굳이 dummy 1byte를 붙인 이유는 컴퓨터의 자료표현에 대한
속성때문이다.
2의 배수로 올라가는 2^32bit(4byte)형태라면 쉽게 접근이 가능하지만
2^24bit 형태라면 위의 경우보다 메모리 접근시 연산이 더 필요하다
- 자세한 설명은 뒤로 미루겠다.(안 할지도 모른다) System programming 영역이니까.

이 palette부분은 256 color까지만 존재한다.
그 이상의 색상을 표현할땐 palette부분이 없다.

3. image data
1bit(2color) ~ 8bit(256color) 구조 까지는 palette에 대한 index만 가지고 있다.
이 인덱스는 0~255까지가 범위이다.
이 이상 벗어나게되면(색상이 더욱 많아지면) 1byte 만으로는 표현할수가 없어서
palette에 대한 index대신 직접색상 정보를 data부분에 직접기록한다.
출처: http://www.munhi.com/cgi-bin/zboard/view.php?id=sw_development&page=1&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=9

'Application Programming' 카테고리의 다른 글

쓰레드의 종류  (0) 2014.11.25
Bitmap 구조 2  (0) 2010.01.18
Posted by Finebe
,