[Tips] ビットマップファイルの書き込み
書き込む画像データの作成
まず,データを用意する.
データは,1次元配列で以下のようなコードで用意する.
int x,y;
int width = 131;
int height= 121;
unsigned char *pixel = (unsigned char*)malloc(sizeof(unsigned char)*width*height*3);
for( x=0;x<width;x++){
for( y=0;y<height;y++){
int pix1=0,pix2=0;
if(x<width/2)
pix1 = 255;
if(y<height/2)
pix2 = 255;
*(pixel+3*(x+y*width) )=pix1;
*(pixel+3*(x+y*width)+1)=pix2;
*(pixel+3*(x+y*width)+2)=0;
}
}
このデータは左上四半分が黄色,右上四半分が緑色,左下四半分が赤色,右下四半分が黒色となる.
以下はその画像である.

画像データの書き込み
このデータを以下のWriteBitmapで書き込む.
まず,ビットマップファイルのヘッダを準備する.改めて書き込む必要があるのは,画像のサイズに関する部分だけだ.
// calculate alignment size if( nWidth*3%4 == 0) writeWidth = nWidth*3; else writeWidth = nWidth*3 + 4 - (nWidth*3)%4;
この部分で,ビットマップファイルの横幅のマージンを入れたバイト単位の横幅サイズを計算する.
そして,この構造体をそのまま書き込まないようにする.
一般的にC言語等では,構造体のサイズを2バイト単位(だったかな?)で確保するため,構造体をそのままファイルに書き込むと,空白のダミーデータが書き込まれてしまう.(確かこれを回避する構造体の宣言方法もあったはず)
よって,ビットマップファイルの時は,構造体の中のデータをひとつずつ書き込んでいく.
最後にピクセルデータを書き込んでいく.
ピクセルデータは,フォーマットに従い,マージンを書き込む必要がある.
int WriteBitmap(char*pFileName, unsigned char *pPixel,int nWidth, int nHeight)
{
FILE *fp;
BitmapHeader header;
BitmapInfoHeader info;
int x,y;
unsigned char dummy=0;
int writeWidth=0;
// open file
if(!( fp = fopen(pFileName, "wb") ))
return 0;
// initialize headers
InitHeaders(&header, &info);
// image size
info.m_nWidth = nWidth;
info.m_nHeight = nHeight;
// calculate alignment size
if( nWidth*3%4 == 0)
writeWidth = nWidth*3;
else
writeWidth = nWidth*3 + 4 - (nWidth*3)%4;
// set file size
header.m_nFilesize =
writeWidth*nHeight // bitmap size
+ 14 // header size
+ 40; // information header size
#ifdef __ENDIAN // Macのときは__ENDIANを定義し,エンディアン変換を行う.
SwapByteOrderHeaders(&header, &info);
#endif
// write headers
WriteHeader(&header,fp);
WriteInfoHeader(&info,fp);
// write pixels
for( y=nHeight-1 ; y>=0 ; y--){
// sort RGB -> BGR
for( x=0 ; x < nWidth ; x++ ){
fwrite((pPixel+3*(x+nWidth*y)+2),sizeof(unsigned char),1,fp);
fwrite((pPixel+3*(x+nWidth*y)+1),sizeof(unsigned char),1,fp);
fwrite((pPixel+3*(x+nWidth*y) ),sizeof(unsigned char),1,fp);
}
// fill in margin memory with zero
if( nWidth*3%4 != 0)
for( int j=0;j<4-(nWidth*3)%4;j++)
fwrite(&dummy,sizeof(unsigned char),1,fp);
}
fclose(fp);
return 1;
}
サンプルコード
http://code.google.com/p/sonson-code/source/browse/#svn/trunk/src/bitmapSrc