![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
BITMAPをバイナリデータから作成しています。BITMAPINFO構造体のbiBitcountからカラーテーブルの色を調べようと思ったんですが8Bit(256色)で表示されるBITMAPの場合、カラーテーブルのデータは、
for(; l < (1 << bmpInfo.bmiHeader.biBitCount); l++) {
printf("bmpInfo.bmiColors[%d].rgbBlue = %d\n",l,bmpInfo.bmiColors[l].rgbBlue);
printf("bmpInfo.bmiColors[%d].rgbGreen = %d\n",l,bmpInfo.bmiColors[l].rgbGreen);
printf("bmpInfo.bmiColors[%d].rgbRed = %d\n",l,bmpInfo.bmiColors[l].rgbRed);
}
で表示しているのですがこの方法で正しいのでしょうか?
あと、4bitの場合、16色となり、1バイト=2ピクセルとなり、上記とはまた違ったやり方でないとダメなんでしょうか?
No.1ベストアンサー
- 回答日時:
こんばんは。
カラーテーブルと言う事はパレットの事でしょうか。でしたら、「8, 4, 1」bitの何れであっても、質問に記載されている手段で問題無いと思います。
実はpbmpInfo->bmiHeader.biClrUsedに使用されているパレット個数が記述されています。
しかし、本来なら記述するべきなのですが、記述する事を放棄しているアプリも存在するので(事もあろうかMSペイント)、(1 << pbmpInfo->bmiHeader.biBitCount)とした方が良いかもしれません。以下はbmpファイルを開いてパレットを出力します。参考程度に。
#include<windows.h>
#include<stdio.h>
int main()
{
HANDLE hFile = NULL;
LPBYTE pBuffer = NULL;
try
{
hFile = ::CreateFile("test.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
throw("file open error");
DWORD dwComplete = 0;
const DWORD dwSize = ::GetFileSize(hFile, NULL);
if(dwSize < sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))
throw("file is wrong");
pBuffer = static_cast<LPBYTE>(::malloc(dwSize));
if(pBuffer == NULL)
throw("out of memory");
::ReadFile(hFile, pBuffer, dwSize, &dwComplete, NULL);
BITMAPINFO* pbmpInfo = reinterpret_cast<BITMAPINFO*>(&pBuffer[sizeof(BITMAPFILEHEADER)]);
if(pbmpInfo->bmiHeader.biBitCount != 8 &&
pbmpInfo->bmiHeader.biBitCount != 4 &&
pbmpInfo->bmiHeader.biBitCount != 1)
throw("no palette");
int paletteLen = pbmpInfo->bmiHeader.biClrUsed;
if(paletteLen == 0)
paletteLen = 1 << pbmpInfo->bmiHeader.biBitCount;
for(int l = 0; l < paletteLen; l++)
{
printf("bmpInfo.bmiColors[%d].rgbBlue = %d\n",l,pbmpInfo->bmiColors[l].rgbBlue);
printf("bmpInfo.bmiColors[%d].rgbGreen = %d\n",l,pbmpInfo->bmiColors[l].rgbGreen);
printf("bmpInfo.bmiColors[%d].rgbRed = %d\n",l,pbmpInfo->bmiColors[l].rgbRed);
}
}
catch(LPCSTR pszErr)
{
printf("error : %s\n", pszErr);
}
::free(pBuffer);
::CloseHandle(hFile);
return 0;
}
この回答への補足
実はまだBITMAP構造には疑問を持っているところがあり、全てを把握してないせいか上記でのソースで理解できないところがあるので質問なんですが、
BITMAPINFO* pbmpInfo = reinterpret_cast<BITMAPINFO*>(&pBuffer[sizeof(BITMAPFILEHEADER)]);
でLPBYTEのアドレスを渡しているのですが、何故sizeof(BITMAPFILEHEADER)]);なんですか?pBufferの大きさはファイルサイズ分ですよね?
実に分かりやすい説明をして貰えて嬉しいです。
8bitでも4bitでも関係ないんですね。 早速試してみようと思います。 全ソースを載せてくださってありがとうございます。
No.2
- 回答日時:
こんばんは。
補足頂きました。pBufferはファイルを丸ごと吸い上げた状態です。
バッファ内のBITMAPINFO情報がある位置へ移動する為に、バッファの先頭からBITMAPFILEHEADERのサイズ分だけずらさなければいけません。
↓ファイル内の構造
BITMAPFILEHEADER
BITMAPINFOHEADER(BITMAPINFO::bmiHeader)//この位置に移動する為
ある場合はカラーテーブル[1~255](BITMAPINFO::bmiColors[1~255])※配列は0を基準
ビットイメージ
BITMAPINFO情報ある場所まで配列を移動させ、そこからカラーパレットの情報を読み上げるんですね。
分かりました。 補足の回答ありがとうございます。
ネットで調べてたんですがよく分からなかったんで質問してみました。答えてくれる人がいて助かりました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# LU分解法のピボット選択機能実装について(C言語・gcc-9) 1 2022/07/22 15:20
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンパイルエラーについて
-
LU分解法のピボッティングにつ...
-
テキストカーソル位置の取得
-
C言語です このプログラミング...
-
10個出力で改行したいのですが...
-
C言語の二項分布
-
printfの出力内の文字をdefine...
-
LU分解法のピボット選択機能実...
-
【C言語教えてください】sin波...
-
4の倍数を論理演算で表す。。
-
C言語の勉強しています。すみま...
-
空Enterの扱い方
-
C言語 文字列の比較 compare
-
C言語での、年複利の計算方法...
-
printf で二進表示を行いたい。
-
switch分のケースを範囲数?に...
-
scanfに文字が入力されたときに...
-
if文がコンパイルエラーを起こ...
-
C言語でマウス入力(クリックや...
-
なぜgccはstdio.hをインクルー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
10個出力で改行したいのですが...
-
printf で二進表示を行いたい。
-
【C言語教えてください】sin波...
-
strcmp
-
コンパイルエラーについて
-
c言語でAからZまでを表示する...
-
コマンドラインに出力した文字...
-
cshの文字列操作(0埋め)
-
4の倍数を論理演算で表す。。
-
C言語 プログラミング
-
%P と %X の違い
-
8人分のテストの点数を入力し、...
-
C言語での、年複利の計算方法...
-
printf( " %2d", p * q );
-
hit&bolwのプログラミングがで...
-
scanfに文字が入力されたときに...
-
error C2143: 構文エラー : ';'...
-
printfの出力内の文字をdefine...
-
テキストカーソル位置の取得
-
unsigned int型について
おすすめ情報