• ベストアンサー

WINDOWSのペイントで作るBMPファイルの構成

ペイントで作るBMPファイルの内容が詳しく解説しているサイト等ご存知でしたら教えてください。 BMPファイルのフォーマット等の解説はいろいろありますが実際に作ったファイル内容を見てみますと色数では18hでWINDOWS仕様には無い?(OS/2ではフルカラー?)ですとか2×2ピクセル、3×3ピクセル等小さいファイルを作ってみますと余計な00hが存在する様です。 R,G,Bの3byteで1ピクセルが連続するものと思っていますが途中で余計な00hがあります。 このあたりを理解したいと思っております。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.3

> 色数では18hでWINDOWS仕様には無い?(OS/2ではフルカラー?) Windowsでも24bitの事を指し、いわゆるフルカラーですよ。 No.1さんのリンク先の説明だと、 | イメージデータにおいて1ピクセルを表現するのに必要なビット数が符号無し整数値で入る。 | 値は0、1、4、8、16、24、32のいずれかとなり、 > 2×2ピクセル、3×3ピクセル等小さいファイルを作ってみますと余計な00hが存在する様です。 同様に、 | 更に、行データは必ず4バイトの整数倍のサイズでなければならない。 の仕様に基づく00hです。 4×4、4×3、8×3では余計な00hは入らないハズです。

その他の回答 (3)

noname#17908
noname#17908
回答No.4

データが4バイトの倍数だった場合のメリットとして、 32bit CPUの汎用レジスタで一気にメモリコピーができます。 BMPはビデオカードのデバイスドライバーとも密接に 関連している形式ですので、データが15バイトだった場合、 4バイトコピー3回、1バイトコピー3回になります。 これをアセンブラで書くと面倒なんです。

  • yosi_yosi
  • ベストアンサー率35% (165/468)
回答No.2

色数が18Hではなくビット深度が18H(=24)ということでしょう。つまり24ビットカラーのBMPファイルです。これは基本的なことですので、調べればすぐに分かると思いますが... また、BMPファイルの色の並び(24ビットカラー)はR,G,Bではなく、B,G,Rです。2x2や3x3の場合になぜ00Hが入っているかというと、1行分のデータは4バイト境界にしなくてはいけないからです。2x2の場合には1行のデータは2x3=6バイトになりますから、4バイト境界にするためには2バイト分の余分なデータ(これが00H)が必要なわけです。 さらに、BITMAPINFOHEADERのbiHeightが0未満の場合はそのまま読めばいいですが、そうでない場合には画像の上下がひっくり返っています。これにも注意が必要です。 その他の色数ではパレットの存在もありますから、とりあえずは24ビットカラーのBMPファイルでいろいろと学習してください。これが一番単純で分かりやすいはずです。

  • hamuzo
  • ベストアンサー率48% (88/180)
回答No.1

私は詳しくないのですが こんなページを見つけました。 BMPファイル仕様

参考URL:
http://www.ruche-home.net/

関連するQ&A

  • bmpよりpngのほうがファイルサイズが大きいです

    24bit per pixelの32×32の画像があるのですが, pngファイルの方が4312バイトで、bmpファイルの方が3128バイトと、圧縮しているpngファイルの方が bmpファイルより大きくなってしまっています.理由が分かりません. また、bmpファイルのサイズも単純に考えれば 32×32×3=3072バイトのはずですが、サイズが一致しないのはなぜでしょうか。 理由が分かる方教えてください。よろしくお願いします。

  • bmp file でエラーがでます。

    windows-me からwindows2000へアップグレードしてから、 ビットマップファイルをダブルクリックすると以下のメッセージがでます。「ファイル'c:\xxxx.bmp'(またはその構成ファイル)が見つかりません。パスおよびファイル名が正しいか、必要なライブラリーがすべて利用可能かどうか、確認してください。」 ただし、ファイルそのものは開いてくれて、問題はないのですが、毎回このメッセージがでます。また、開くアプリケーションをMSペイントにしても駄目で、当然アイコンもWINDOWSのLOGのようなマークのままです。 今のところ、bmpのみでjpgやgifでは、このメッセージはでません。どうかよろしくお願いいたします。

  • ペイントについて

    現在、画面の領域を1024×768ピクセルにしてパソコンを使用しています。画面コピーを取る際にはペイントで印刷をしているのですが、この画面領域ですと一枚の用紙に収まらず、はみだしてしまいます。 他のソフトを使用すれば解決するのでしょうが、ペイントで一枚の用紙に印刷するには、何か設定が必要なのでしょうか。 ※仕様OS Windows98

  • BMPファイルの輝度を配列で表す

    はじめての投稿です。よろしくお願いします。 ただいまC++でBMPファイル処理の勉強をしています。わからないところがBMPファイル(480×640)を読み込みその画像の輝度を配列(480×640)でテキストファイルに書き込みたいのですが、途中から配列がずれてしまいます。 各ピクセルからRGB値を読み込み輝度yを求めてるのですが、最初にBMPファイルのヘッダーを読み込んでしまってるんでしょうか?どなたかご教授お願いします。プラットフォームはWin32です。 以下にソースコードを載せます。 #include <stdio.h> #include <stdlib.h> #include <windows.h> #pragma warning( disable : 4996 ) #pragma warning( disable : 4244 ) #pragma warning( disable : 4700 ) int main(void){ BITMAPFILEHEADER BmpHead = { 0 }; int R, G, B, y; FILE *fpi, *fpy; /* y値出力のオープン */ if((fpy=fopen("test.txt", "a")) == NULL){ fprintf(stderr, "output file open error\n"); exit(1); } /*画像の読込*/ if((fpi = fopen("filename.bmp","rb")) != NULL ){ fread( &BmpHead, sizeof(BmpHead), 1, fpi ); fseek( fpi, BmpHead.bfOffBits, SEEK_SET ); int h,l; static int matrixy[480][640]; //画像のサイズ480×640 for(h=0;h<480;h++){ for(l=0;l<640;l++){ B = fgetc(fpi); G = fgetc(fpi); R = fgetc(fpi); y=0.298912*R+0.586611*G+0.114478*B; /*輝度の算出*/ fprintf(fpy,"%f,",y); } fprintf(fpy,"\n"); } } fclose(fpy); fclose(fpi); } よろしくお願いします。

  • BMPファイルがクイックビュアーでしか開かない

    説明が長くなります。 フォルダオプション→登録されているファイルの種類の中からビットマップイメージの項目が消えてしまいました。それでbmpのアイコンがWindowsのフラッグに変わってしまいました。それで、新たにビットマップイメージを追加しようとすると「拡張子BMPは~で使用しています。他の拡張子を選択して下さい」というメッセージが出ます。~は今はアンインストールしたソフト名でした。 そこで、レジストリエディタで調べてみると、HKEY-CLASSES-ROOT-bmpのところに~が表示されていました。それで、~をPaintPictureに変えて見ました。 すると質問のタイトルのようになってしまいました。(それまではアイコンはフラッグのままでペイントで開いていました) 今はマウスの左2回クイックでは何の反応も無く、右クリックをすると一覧の1番上にクイックビュアーの項目があり、そこをクリックすることで表示されます。 原因を考えてみると、フリーソフトに不要なDLLファイルを選び出し、削除できるソフトがありそれを実行した結果だと思われます。それからいろんな不都合が出てきましたから…。 正常なBMPのアイコンとアイコンをダブルクイックによって、ペイントで開ける方法を教えていただけると本当に助かります。OSはWindows98です。

  • フォトショップでbmpが開けない保存できない

    久しぶりにビットマップファイルを使う機会ができましたが フォトショップで開きません。保存もできません。 【環境】 windows7(64bit) フォトショップCS5(アップデート最新) 【状況】 bmpファイルが開けない、保存できるファイル形式にもない。 「要求された操作を完了できません。ドキュメントの種類が適切ではありません」 すべてのbmp、以前にCS2で編集したbmpファイルも開けなくなっています。 windowsのペイントで新規作成したbmp(24bit)も開けない。 フォトショップで新規作成したデータもbmpで保存不可。 カラーモードはRGB、8bit。 インデックスカラーでシステム(windows)でも× レイヤーも使用なし。 他に何か思い当たる原因がありましたら教えてください。 ※手間はかかりますが、とりあえずwindowsペイントと併用して作業はできてます。

  • BMPファイルへの書き込みができない

    このプログラムは、左半分を黒、右半分を白の画像をBMPファイルに出力しようとしています。(出来ていません) プログラムの下に質問書いてます!お願いします! #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct{ char *filename; int x; int y; int width; int height; unsigned char data[80][100]; } BMP_DATA; static void WriteBmp(char *filename, BMP_DATA Image) { unsigned long Bmp_size;/*BMPファイルのサイズ*/ unsigned int Bmp_info_header_size;/*情報ヘッダのサイズ*/ unsigned int Bmp_header_size;/*ヘッダのサイズ*/ long Bmp_width;/*幅*/ long Bmp_height;/*高さ*/ unsigned short Bmp_planes;/*プレーン数*/ unsigned short Bmp_color;/*色 = 1[bit] (黒か白かだけ)*/ long Bmp_image_size;/*画像部分のサイズ*/ long Bmp_xppm;/*水平解像度*/ long Bmp_yppm;/*垂直解像度*/ int i,j; unsigned char Bmp_headbuf[54]; /*ヘッダ*/ unsigned char Bmp_Data[13]; FILE *Out = fopen(filename, "wb"); if(Out==NULL){ fclose(Out); exit(1); } /* ヘッダ情報の準備 */ Bmp_info_header_size = 40; Bmp_header_size = 54; Bmp_planes = 1; Bmp_color = 1; Bmp_image_size = Image.height * Image.width; Bmp_xppm = 0; Bmp_yppm = 0; Bmp_size = Bmp_image_size + Bmp_header_size; Bmp_headbuf[0] = 'B'; Bmp_headbuf[1] = 'M'; memcpy(Bmp_headbuf+2, &Bmp_size, sizeof(Bmp_size)); Bmp_headbuf[6] = 0; Bmp_headbuf[7] = 0; Bmp_headbuf[8] = 0; Bmp_headbuf[9] = 0; memcpy(Bmp_headbuf+10, &Bmp_header_size, sizeof(Bmp_header_size)); Bmp_headbuf[11] = 0; Bmp_headbuf[12] = 0; Bmp_headbuf[13] = 0; memcpy(Bmp_headbuf+14, &Bmp_info_header_size, sizeof(Bmp_info_header_size)); Bmp_headbuf[15] = 0; Bmp_headbuf[16] = 0; Bmp_headbuf[17] = 0; memcpy(Bmp_headbuf+18, &Image.width, sizeof(Bmp_width)); memcpy(Bmp_headbuf+22, &Image.height, sizeof(Bmp_height)); memcpy(Bmp_headbuf+26, &Bmp_planes, sizeof(Bmp_planes)); memcpy(Bmp_headbuf+28, &Bmp_color, sizeof(Bmp_color)); memcpy(Bmp_headbuf+34, &Bmp_image_size, sizeof(Bmp_image_size)); memcpy(Bmp_headbuf+38, &Bmp_xppm, sizeof(Bmp_xppm)); memcpy(Bmp_headbuf+42, &Bmp_yppm, sizeof(Bmp_yppm)); Bmp_headbuf[46] = 0; Bmp_headbuf[47] = 0; Bmp_headbuf[48] = 0; Bmp_headbuf[49] = 0; Bmp_headbuf[50] = 0; Bmp_headbuf[51] = 0; Bmp_headbuf[52] = 0; Bmp_headbuf[53] = 0; /* ヘッダ情報書き出し */ fwrite(Bmp_headbuf, sizeof(unsigned char), Bmp_header_size, Out); /* 画像データ書き出し */ for(i=0;i<13;i++) Bmp_Data[i] = 0; for(i=0; i<Image.height; i++){ for(j=0; j<Image.width; j++){ int index = j/8; if(j%8 == 0){ Bmp_Data[index] = Image.data[i][j ] * 128 + Image.data[i][j+1] * 64 + Image.data[i][j+2] * 32 + Image.data[i][j+3] * 16 + Image.data[i][j+4] * 8 + Image.data[i][j+5] * 4 + Image.data[i][j+6] * 2 + Image.data[i][j+7]; } } Bmp_Data[12] = (Bmp_Data[12] & 0xf0); fwrite(Bmp_Data, sizeof(unsigned char), 20, Out); /* ○ */ } fclose(Out); } int main() { BMP_DATA Image; int line = 0; int i,j; Image.x = 0; Image.y = 0; Image.width = 100; Image.height = 80; if(line == 0){ for(i=0; i<Image.height; i++){ for(j=0; j<Image.width; j++){ Image.data[i][j] = 1; } } } while(1){ /* BMPファイルデータを編集 */ for(j=0; j<Image.width; j++){ if(j < 50){ Image.data[line][j] = 0;//black }else{ Image.data[line][j] = 1;//white } } /* すべての列を編集したら、再描画する */ if(line == 63){ /* BMPファイルに書込む */ WriteBmp("display.bmp", Image); break; } line++; } return 0; } 以下の条件で、BMPファイルへ書き込もうとしています ・色の深さ1(黒か白) ・画像のピクセルサイズ(横100×縦80) fwrite関数で1列ずつ書き込もうとしているのですが、 この関数は1バイトずつしか書き込めないみたいで、100ビット書き込もうと思うと、 最低でも104ビット書き込まなくてはならない状況になります。 まず、この4ビットはどう処理すればいいのでしょうか?? あと、display.bmpのファイルがある状態で、プログラムを実行するとちゃんと動くのですが、 プログラム中の○のところのfwrite関数の第三引数を13にすると、BMPファイルが壊れて閲覧できなくなります。(ある程度大きい数字だと、BMPファイルは壊れないのですが、ぐちゃぐちゃの絵になります) その理由もわかりません。 汚い文章&プログラムですが よろしくお願いします><

  • Windowsアクセサリのペイント

    Windows98をつかっています。 ペイントで描いた絵を保存する時に ファイルの種類を選択しますよね。 前はjpegが選べて、jpegで保存できていたのですが 修理に出してハードディスクのフォーマット処理してから bmpでしか保存できなくなってしまいました。 以前のようにペイントで描いた絵をjpegで保存したいのですが どうすればできるようになりますか? 変換ソフトを使う以外での対処法を教えてください。 よろしくおねがいします。

  • BMPのフォーマットの詳細について教えてください!

    BMP(といってもいくつかありますねぇ・・) とりあえず、Windowsの独立DIBのBMPで、 RLE圧縮されていないバージョンのBMPのフォーマット(というか仕様?)、 に関する情報、を探しています。 例えば、私がGIF連結システムを作ったときに 参考にさせていただいた仕様は次のようなものでした。 GIF Header Offset Length Contents 0 3 bytes "GIF" 3 3 bytes "87a" or "89a" 6 2 bytes <Logical Screen Width> 8 2 bytes <Logical Screen Height> 10 1 byte bit 0: Global Color Table Flag (GCTF) bit 1..3: Color Resolution bit 4: Sort Flag to Global Color Table bit 5..7: Size of Global Color Table: 2^(1+n) 11 1 byte <Background Color Index> ・・・などなどなど でした。 こういう感じで、BMPのフォーマット仕様書ってネット上にころがってないでしょうか? とりあえず必要なのは、どこのバイナリデータが何を示しているのか? という情報です。 やりたいことは、BMPのパレット番号を(画像を維持したまま) 切りかえるコマンドツールの作成、もしくは同様のコマンドラインツールの入手です。 (今は普通のWindowsツールで、そのツールでは、操作の都合上、連続処理することが出来ないのです) 数百個のBMP画像ファイルのパレット番号を機械的に入れ替えたいので そのようなツールの作成、もしくは入手をもくろんでいます。 いろいろな角度からの解決法を提供していただいても結構です。 Perlで、GDなどを使って簡単に解決できるよ!というご意見や、 C/C++ライブラリでこのように書けば・・・というご意見、 などなどでも結構です。 よろしくお願いします m(_ _)m

  • BMP画像ファイルの読み書き

    Visual StudioのC言語により、ビットマップ形式の画像に対するプログラミングで 簡単な背景差分のプログラムを作成しています。 背景画像と対象画像2枚を読み込み色の差を取り、 差の値が背景の値と近ければ背景とみなし白で塗りつぶし、 物体だけを表示した画像を生成するようなプログラムです。 1枚のみの画像は以下のプログラムで作動しますが、連続した画像(01.bmp 02.bmp ・・・・100.bmp) を読み込み上記の処理をする場合にはどうすればよいのでしょうか? 分かりにくくて申し訳ないですが、よろしくお願いします。 #include "BMPData.h" #include <math.h> int main(){ int a=150; int i,j; int r,g,b; int ir,ig,ib; int diff; BMPStruct bmp_bg; BMPStruct bmp_oj; BMPStruct bmp; RGB rgb_bg; RGB rgb_oj; RGB rgb; RGB rgb_w; rgb.r = 255; rgb.g = 255; rgb.b = 255; rgb_w.r = 0; rgb_w.g = 0; rgb_w.b = 0; readBMP(&bmp_bg, "back.bmp"); //背景画像の読み込み readBMP(&bmp_oj, "01.bmp"); //対象画像の読み込み makeBMP(&bmp,640, 480, rgb); //出力用画像を生成する for(i=0; i<640; i++){ for(j=0; j<480; j++){ getColor(bmp_bg, &rgb_bg,i,j);  //背景画像の色を取得 getColor(bmp_oj, &rgb_oj,i,j);  //対象画像の色を取得 //rgbそれぞれの値の差 r = rgb_bg.r - rgb_oj.r; g = rgb_bg.g - rgb_oj.g; b = rgb_bg.b - rgb_oj.b; //絶対値 ir = abs(r); ig = abs(g); ib = abs(b); //色の差 diff = ir + ig + ib; //背景かどうかの判定 if(diff>a){ putColor(bmp, rgb_w, i, j); //色の差が大きければ出力画像に対象画像の色をそのまま出力 } else{ putColor(bmp, rgb, i, j); //色の差が小さければ白を出力 } } } writeBMP(bmp, "image01.bmp"); }