BMP 파일구조 김성영교수 금오공과대학교 컴퓨터공학부
학습목표 BMP 파일의구조및그특징을설명할수있다. 파일헤더및비트맵정보헤더의주요필드를구분하고그역할을설명할수있다. C언어를사용하여 BMP 파일을처리할수있다. 2
BMP 파일구조 File Header (BITMAPFILEHEADER) Bitmap Info. Header (BITMAPINFOHEADER) Headers of BMP LUT (RGBQUAD) Image Data 3
파일헤더 (File Header) typedef struct tagbitmapfileheader { WORD bftype; // Specifies the file type // It must be BM (4D42) DWORD bfsize; // 파일의크기 (byte) WORD bfreserved1; // reserved ( 항상 0) WORD bfreserved2; // reserved ( 항상 0) DWORD bfoffbits; // 픽셀데이터의시작오프셋 } BITMAPFILEHEADER; 4
비트맵정보헤더 (Bitmap Info Header) typedef struct tagbitmapinfoheader { DWORD bisize; // 구조체의크기 (bytes) LONG biwidth; // 비트맵의가로길이 (pixels) LONG biheight; // 비트맵의세로길이 (pixels) WORD biplanes; // 비트플레인수 ( 항상 1) WORD bibitcount; // 픽셀당비트수 (1,4,8,16,24,32) DWORD bicompression; // 압축유형 (BI_RGB) DWORD bisizeimage; // 비트맵데이터의크기 (bytes) LONG bixpelspermeter; // 수평해상도 (pixels/meter) LONG biypelspermeter; // 수직해상도 (pixels/meter) DWORD biclrused; // LUT에포함된칼라인덱스의개수 DWORD biclrimportant; // 비트맵을화면에출력하기위해 // 사용된칼라인덱스의개수 } BITMAPINFOHEADER; 5
팔레트 (Palette) typedef struct tagrgbquad { BYTE rgbblue; // B component BYTE rgbgreen; // G component BYTE rgbred; // R component BYTE rgbreserved1; // reserved } RGBQUAD; 6
BMP 파일예제 (1) 비트맵파일의내부값 BMP 파일구조확인실습 sample.bmp 7
BMP 파일예제 (2) 항목값항목값 영상데이터오프셋 영상가로길이 영상세로길이 픽셀당비트수 비트맵데이터크기 참조표의인덱스개수 8
BMP 파일특징 (1) 10 A 2 차원배열 (data) A data[1][2] 8 1 차원배열 (data) A data[12] A 9
BMP 파일특징 (2) 0 101 102 104 203 204 305 306 4997 4998 5099 (2, 1) 102 x 50 8bit gray-scale image (2, 1)? 0 101 103 105 102 104 106 207 208 311 312 5095 5096 5199 (2, 1) 10
BMP 파일특징 (3) 비트맵데이터는파일내부에서수직으로반전되어저장 for(y=0; y<biheight; y++) { for(x=0; x<biwidth; x++) { GrayImg[y][x] = Mem[(biHeight-y-1)*rwsize+x]; } } 비트맵데이터의각행은반드시 4 bytes 의배수임 #define WIDTHBYTES(bits) (((bits)+31)/32*4) rwsize = WIDTHBYTES(biBitCount*biWidth); 예 ) 가로길이가 102 인 8bit 그레이스케일영상 ((8*102)+31)/32*4 = (816+31)/32*4 = 847/32*4 = 26*4 = 104 11
Example Inverting Image /* */ 이프로그램은 8bit 그레이스케일영상의픽셀값을반전한후트루칼라포맷의영상으로저장한다. #include <stdio.h> #include <windows.h> #define WIDTHBYTES(bits) (((bits)+31)/32*4) typedef unsigned char BYTE; int main() { FILE *file; // file pointer BITMAPFILEHEADER hf; // 파일헤더 (bmp file header) BITMAPINFOHEADER hinfo; // 비트맵정보헤더 (bitmap information header) int rwsize, rwsize2; // 라인당바이트수 (bytes per a line) BYTE *lpimg; // 입력데이터포인터 (pointer for input image data) BYTE *lpoutimg; // 출력데이터포인터 (pointer for output image data) int x, y; 12
Cont d // 입력영상파일을연다 file=fopen ("input.bmp", "rb"); if(file==null) { printf("there is no file!!!\n"); return -1; } fread (&hf, sizeof(bitmapfileheader), 1, file); // 파일헤더읽음 if(hf.bftype!=0x4d42) // BMP 포맷 ('BM') 인지를확인 return -1; fread (&hinfo, sizeof(bitmapinfoheader), 1, file); // 비트맵정보헤더읽음 printf("image Size: (%3dx%3d)\n", hinfo.biwidth, hinfo.biheight); // 8 bit 회색톤영상만을입력으로받음 if(hinfo.bibitcount!= 8 hinfo.biclrused!= 0) { printf("bad File format!!\n"); return -1; } // 입출력데이터를위한라인당바이트수계산 rwsize = WIDTHBYTES(hInfo.biBitCount*hInfo.biWidth); // 입력영상 rwsize2 = WIDTHBYTES(24*hInfo.biWidth); // 출력영상 13
Cont d fseek (file, hf.bfoffbits, SEEK_SET); // 비트맵데이터가시작되는위치로 // 파일포인터를이동 // 입력영상데이터를위한메모리할당 lpimg = (BYTE *)malloc(rwsize*hinfo.biheight); // 영상데이터를입력영상으로부터읽음 fread (lpimg, sizeof(char), rwsize*hinfo.biheight, file); fclose (file); // 출력영상데이터를위한메모리할당 lpoutimg = (BYTE *)malloc(rwsize2*hinfo.biheight); for(y=0; y<hinfo.biheight; y++) { for(x=0; x<hinfo.biwidth; x++) { lpoutimg[y*rwsize2+3*x+2] = 255-lpImg[y*rwsize+x]; /* R */ lpoutimg[y*rwsize2+3*x+1] = 255-lpImg[y*rwsize+x]; /* G */ lpoutimg[y*rwsize2+3*x+0] = 255-lpImg[y*rwsize+x]; /* B */ } } 14
Cont d // 트루칼라포맷으로변환영상을저장 hinfo.bibitcount = 24; hinfo.bisizeimage = rwsize2*hinfo.biheight; hinfo.biclrused = hinfo.biclrimportant = 0; hf.bfoffbits = 54; // There is no palette hf.bfsize = hf.bfoffbits + hinfo.bisizeimage; file = fopen("output.bmp", "wb"); fwrite (&hf, sizeof(char), sizeof(bitmapfileheader), file); fwrite (&hinfo, sizeof(char), sizeof(bitmapinfoheader), file); fwrite (lpoutimg, sizeof(char), rwsize2*hinfo.biheight, file); fclose(file); // 메모리해제 free(lpoutimg); free(lpimg); } return 0; 15
Cont d 16
Lab. 이전예제에대해다음과같이기능을확장하라. 트루칼라 (true color) 포맷을지원 입력가능포맷 : 8bit gray-scale, true color images 출력포맷 : true color 영상좌측상단에 50x50 크기의사각형을그림 회색톤영상은밝기값 128, 칼라영상은빨간색 (255,0,0) 을사용 수업용게시판에있는테스트영상사용 Gray-scale image: testg.bmp, TVG.bmp True color image: test.bmp, TV.bmp Character Set : 멀티바이트문자집합사용 17
Cont d 18
학습정리 (1) 1. BMP 파일구조 File Header (BITMAPFILEHEADER), Bitmap Information Header (BITMAPINFOHEADER), LUT (RGBQUAD) 및 Image Data로구성 2. BMP 파일구조의특징 영상데이터는상하가반전되어있음 영상의각행의데이터양은 4바이트의배수이어야함 19
학습정리 (2) 3. File Header BMP 식별자 ("BM"), 파일크기및픽셀데이터의시작위치등의정보 포함 4. Bitmap Information Header 영상가로및세로길이, 픽셀당비트수, 영상데이터크기및 LUT 에포 함된엔트리개수등의정보포함 20