BMP 파일처리 김성영교수 금오공과대학교 컴퓨터공학과
학습내용 영상반전프로그램제작 2
Inverting images out = 255 - in 3
/* 이프로그램은 8bit gray-scale 영상을입력으로사용하여반전한후동일포맷의영상으로저장한다. */ #include <stdio.h> #include <windows.h> #define WIDTHBYTES(bytes) (((bytes)+3)/4*4) int main( int argc, char *argv[] ) { FILE *file; // file pointer BITMAPFILEHEADER hf; // 파일헤더 (bmp file header) BITMAPINFOHEADER hinfo; // 비트맵정보헤더 (bitmap information header) RGBQUAD rgb[256]; // Lookup Table int widthstep; // 라인당바이트 (bytes per a line) BYTE *lpimg; // 입력데이터포인터 (pointer for input image data) BYTE *lpoutimg; // 출력데이터포인터 (pointer for output image data) int x, y; if( argc < 3 ) { printf( "Insufficient Input Arguments \n" ); printf( " invertimage input_file ouput_file \n" ); return -1; 4
// 입력영상파일을연다 file = fopen( argv[1], "rb" ); if( file == NULL ) { printf( " 이미지파일을열수없습니다! \n" ); return -1; fread( &hf, sizeof(bitmapfileheader), 1, file ); // 파일헤더읽음 if( hf.bftype!= 0x4D42 ) { // BMP 포맷 ('BM') 인지를확인 printf( "BMP 파일이아닙니다. \n" ); return -1; fread( &hinfo, sizeof(bitmapinfoheader), 1, file ); // 비트맵정보헤더읽음 printf( "Size: (%3dx%3d) \n", hinfo.biwidth, hinfo.biheight ); // 크기정보출력 // 8bit gray-scale 영상을확인 if( hinfo.bibitcount!= 8 hinfo.biclrused!= 0 ) { printf( "8bit gray-scale 영상이아닙니다..!! \n" ); return -1; // Lookup Table 읽음 fread( rgb, sizeof(rgbquad), 256, file ); // Lookup Table 읽음 5
// 입력데이터를위한라인당바이트수계산 widthstep = WIDTHBYTES( (hinfo.bibitcount/8) * hinfo.biwidth ); fseek( file, hf.bfoffbits, SEEK_SET ); // 비트맵데이터가시작하는위치로이동 // 입력데이터를저장하기위한메모리할당 lpimg = (BYTE *)malloc( widthstep * hinfo.biheight ); // 입력영상에서영상데이터를읽음 fread( lpimg, sizeof(byte), widthstep*hinfo.biheight, file ); fclose( file ); // 결과데이터를저장하기위한메모리할당 lpoutimg = (BYTE *)malloc( widthstep * hinfo.biheight ); // 영상반전연산 for( y=0; y<hinfo.biheight; y++ ) { for( x=0; x<hinfo.biwidth; x++ ) { lpoutimg[y*widthstep + x] = 255 - lpimg[y*widthstep + x]; 6
file = fopen( argv[2], "wb" ); fwrite( &hf, sizeof(char), sizeof(bitmapfileheader), file ); fwrite( &hinfo, sizeof(char), sizeof(bitmapinfoheader), file ); fwrite( rgb, sizeof(rgbquad), 256, file ); fseek( file, hf.bfoffbits, SEEK_SET ); // 비트맵데이터가시작하는위치로이동 fwrite( lpoutimg, sizeof(byte), widthstep*hinfo.biheight, file ); fclose( file ); // 메모리해제 free( lpoutimg ); free( lpimg ); return 0; 7
파일 새로만들기 프로젝트 File New Project Project ImageNegative 8
콘솔응용프로그램 빈프로젝트 Console Application Empty Project 9
보기 솔루션탐색기 View Solution Explorer 1. Right-clicking on 소스파일Source Files 2. 추가 새항목 Add New Item main.cpp 10
11
True color images 에대해서도사용가능하도록 소스코드를변경하자! 12
13
/* 이프로그램은 8bit gray-scale 및 true color 영상을입력으로사용하여반전한후동일포맷의영상으로저장한다. */ #include <stdio.h> #include <windows.h> #define WIDTHBYTES(bytes) (((bytes)+3)/4*4) int main( int argc, char *argv[] ) { FILE *file; // file pointer BITMAPFILEHEADER hf; // 파일헤더 (bmp file header) BITMAPINFOHEADER hinfo; // 비트맵정보헤더 (bitmap information header) RGBQUAD rgb[256]; // Lookup Table int widthstep; // 라인당바이트 (bytes per a line) BYTE *lpimg; // 입력데이터포인터 (pointer for input image data) BYTE *lpoutimg; // 출력데이터포인터 (pointer for output image data) int x, y; if( argc < 3 ) { printf( "Insufficient Input Arguments \n" ); printf( " invertimage input_file ouput_file \n" ); return -1; 14
// 입력영상파일을연다 file = fopen( argv[1], "rb" ); if( file == NULL ) { printf( " 이미지파일을열수없습니다! \n" ); return -1; fread( &hf, sizeof(bitmapfileheader), 1, file ); // 파일헤더읽음 if( hf.bftype!= 0x4D42 ) { // BMP 포맷 ('BM') 인지를확인 printf( "BMP 파일이아닙니다. \n" ); return -1; fread( &hinfo, sizeof(bitmapinfoheader), 1, file ); // 비트맵정보헤더읽음 printf( "Size: (%3dx%3d) \n", hinfo.biwidth, hinfo.biheight ); // 크기정보출력 // 8bit gray-scale 및 true color 영상을확인 if( (hinfo.bibitcount!=8 hinfo.biclrused!=0) && hinfo.bibitcount!=24 ) { printf( "8bit gray-scale 영상이아닙니다..!! \n" ); return -1; // Lookup Table 읽음 if( hinfo.bibitcount == 8 ) { fread( rgb, sizeof(rgbquad), 256, file ); // Lookup Table 읽음 15
// 입력데이터를위한라인당바이트수계산 widthstep = WIDTHBYTES( (hinfo.bibitcount/8) * hinfo.biwidth ); fseek( file, hf.bfoffbits, SEEK_SET ); // 비트맵데이터가시작하는위치로이동 // 입력데이터를저장하기위한메모리할당 lpimg = (BYTE *)malloc( widthstep * hinfo.biheight ); // 입력영상에서영상데이터를읽음 fread( lpimg, sizeof(byte), widthstep*hinfo.biheight, file ); fclose( file ); // 결과데이터를저장하기위한메모리할당 lpoutimg = (BYTE *)malloc( widthstep * hinfo.biheight ); 16
// 영상반전연산 if( hinfo.bibitcount == 24 ) { for( y=0; y<hinfo.biheight; y++ ) { for( x=0; x<hinfo.biwidth; x++ ) { lpoutimg[y*widthstep+3*x+2] = 255-lpImg[y*widthStep+3*x+2]; /* R */ lpoutimg[y*widthstep+3*x+1] = 255-lpImg[y*widthStep+3*x+1]; /* G */ lpoutimg[y*widthstep+3*x+0] = 255-lpImg[y*widthStep+3*x+0]; /* B */ else if( hinfo.bibitcount == 8 ) { for( y=0; y<hinfo.biheight; y++ ) { for( x=0; x<hinfo.biwidth; x++ ) { lpoutimg[y*widthstep + x] = 255 - lpimg[y*widthstep + x]; 17
file = fopen( argv[2], "wb" ); fwrite( &hf, sizeof(char), sizeof(bitmapfileheader), file ); fwrite( &hinfo, sizeof(char), sizeof(bitmapinfoheader), file ); if( hinfo.bibitcount == 8 ) { fwrite( rgb, sizeof(rgbquad), 256, file ); fseek( file, hf.bfoffbits, SEEK_SET ); // 비트맵데이터가시작하는위치로이동 fwrite( lpoutimg, sizeof(byte), widthstep*hinfo.biheight, file ); fclose( file ); // 메모리해제 free( lpoutimg ); free( lpimg ); return 0; 18