- ベストアンサー
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
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ビットマップの構造かぁ。学生の頃にやった覚えがあります(笑) VC++をお持ちなら、BITMAPFILEHEADER構造体、BITMAPINFO構造体(中にBITMAPINFOHEADER構造体とRGBQUAD構造体配列が入っています)を調べるといいですよ。各構造体の中身は↓な感じです。 BITMAPFILEHEADER: Offset Length Contents 0 2 ASCIIコードで"BM" 2 4 ファイルサイズ(Byte) 6 2 予約済み:必ず0 8 2 予約済み:必ず0 10 4 ファイル先頭から、イメージデータまでのオフセット(Byte) BITMAPINFO: BITMAPINFOHEADER RGBQUAD ※要素1つの配列 BITMAPINFOHEADER: Offset Length Contents 0 4 この構造体のサイズ 4 4 画像の横幅(Pixel) 8 4 画像の高さ(Pixel) 符号でイメージの格納形式が変わります。 正:bottom-up 負:top-down 12 2 必ず1 14 2 色数(Bit) 16 4 圧縮の種類 20 4 イメージのサイズ(Byte) 24 4 水平解像度(pixels/meter) 28 4 垂直解像度(pixels/meter) 32 4 使用するカラーインデックス数 36 4 重要なカラーインデックス RGBQUAD: Offset Length Contents 0 1 青の輝度 1 1 緑の輝度 2 1 赤の輝度 3 1 必ず0 実際にはBITMAPFILEHEADER、BITMAPINFOHEADERまではどのBMPファイルでも同じですが、RGBQUAD以下の部分は色数によって構造が変わります。 ●カラーテーブルを利用している場合(1,4,8bit形式)は、パレット数分のRGBQUAD構造体が並び、その下にイメージデータ(パレットIndex配列)が入ります。 ●カラーテーブルを利用しない場合(16,24,32bit形式)でも、BITMAPINFOHEADERの「使用するカラーインデックス数」が0でない場合、その数の最適化カラーパレットが存在します。 ●24bit形式の場合、RGB1byteずつの3byteで1pixelを表します。圧縮タイプは必ず0になります。 ●16,32bit形式の場合、圧縮タイプによりデータの構造が変わります。圧縮の種類には、 0:非圧縮 1:8bit用ランレングス 2:4bit用ランレングス 3:非圧縮だがカラーマスクが指定されている があります。 ○0の場合、RGBQUADの位置からイメージデータが配置されます。 16bitでは最上位1bitが無視され、5bitずつRGBの順に使用されます。 32bitでは上位1byteが無視され、1byteずつRGBの順に使用されます。 ○3の場合、RGBQUADの位置から、4byteのカラーマスクが3つRGB順に配置され、その後にイメージデータが続きます。 最適化カラーテーブルが存在する場合、カラーマスクの直後に配置されます。 カラーマスクの値には、WindowsNT/2000とWindows95/98で、異なる制限があります。 イメージデータは、1ラインごとにlong境界に合わせなければならないため、1ラインのデータがlong境界に満たない場合は、隙間はNULLで埋められます。 ※BMP/DIBフォーマットにはWindows形式とOS/2形式があり、ここに書いたものはWindows形式になります。 両者の違いはヘッダの構造体だけで、基本的な構造は変わりません。
その他の回答 (3)
- KojiS
- ベストアンサー率46% (145/312)
VC++を持っているなら、MSDNと VCのヘッダファイルを調べればだいたいわかると思います。 MSDNもキーワードでいろいろ検索すればいろいろ出てきますし。 以前仕事で DOSで作った時はヘッダだけでなんとかなりましたよ。(圧縮されているものは面倒ですが。) 一度適当なサンプルを作ってみると良いと思います。 (ただ表示するだけのものとか)
- SpiralGalaxy
- ベストアンサー率39% (649/1654)
Microsoft の Visual Studio とか MSDN とかに記述されていると思います。 全部引用するわけにはいきませんが、 typedef struct tagBITMAPINFOHEADER{ // bmih DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; typedef struct tagBITMAPINFO { // bmi BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; BITMAPINFOHEADER構造体がヘッダ情報で RGBQUAD構造体が実際のビット列を表します。 ですから、RGBQUAD構造体のビットマップのサイズによってレコード数が可変になるということになります。 最近 bmp を扱うプログラムをやってませんので忘れてしまいましたが、ヘッダ情報のところに次のような記述があるので、ヘッダもいくつかあるようですね。 >Windows NT 3.51 and earlier: Use the BITMAPINFOHEADER structure. > >Windows NT 4.0 and Windows 95: Use the BITMAPV4HEADER structure. > >Windows 98, Windows NT 5.0 and later: Use BITMAPV5HEADER structure. >BMPのフォーマット仕様書ってネット上にころがってないでしょうか? 正式なものが、ちょっとどこにあるかは分かりませんがBITMAPINFOHEADERをキーワードにして goo で検索したら 300以上でてきましたよ。
補足
SpiralGalaxy さん、こんにちわ。 おかげさまの情報で、大体BMPの構造が理解できました。 バイナリを見てわかりそうな程度なので、これなら 充分なんとかなりそうです。 (GIFの場合は、肝心のIMAGEデータ部の圧縮がさっぱり意味不明で泣きましたが、 それに比べれば、IMAGEデータ部がカラーテーブルのインデックスを 指してるだけ(フルカラーでなければ)っぽいので、かなり簡単そうです。 パレットの入れ替えはパレットの並びの入れ替えと、イメージのインデックス値の 入れ替えで大体終わるのではないか? とい考え方でいけそうなので、 やってみようと思います。 貴重な情報ありがとうございました。
- KojiS
- ベストアンサー率46% (145/312)
開発ツールは何を使っていますか? MSDN等で「Bitmap Structures」がありますので調べましょう。
補足
KojiSさん、さっそくのご回答ありがとうございます。 えーと、普段はVC++は使ってないのですが、 一応 VC++ エンタープライズはあります。 Bitmap Structures みてみました。 うーむ。わかるようなわからないような。。。 そこで、BMPファイルの中身をみてみたのですが、、、 肉眼で読めました〔笑 これかんたんなのですね・・・ GIFのときは肉眼では全然不明で仕様を読んで ようやくわかったのですが、 BMP、バイナリ肉眼で読めますねこれ・・・ (まぁ、だからこそDIBなのかもしれないですが・・・) とりあえず、貴重な情報ありがとうございました。 フォーマットがかなり簡単そうなので、これなら何とでもなりそうです。
補足
leaz024 さんこんにちわ。 これは、うまく詳細に知りたいところをわかりやすい形にしていただいたと言う感じです。 こんなに詳しく書いていただいて、本当に痛み入ります。m(_ _)m これだけ様々な情報をいただければ、充分解決しますが、 意外な観点からの解決法を述べられる方がおられるかもし れないので、とりあえず、もう少し締め切りを待とうと思います。 重ね重ね、詳しく教えていただきありがとうございました。