電子書籍の厳選無料作品が豊富!

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ピクセルとなり、上記とはまた違ったやり方でないとダメなんでしょうか?

A 回答 (2件)

 こんばんは。



 カラーテーブルと言う事はパレットの事でしょうか。でしたら、「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の大きさはファイルサイズ分ですよね?

補足日時:2009/11/05 23:22
    • good
    • 0
この回答へのお礼

実に分かりやすい説明をして貰えて嬉しいです。
8bitでも4bitでも関係ないんですね。 早速試してみようと思います。  全ソースを載せてくださってありがとうございます。

お礼日時:2009/11/05 23:22

 こんばんは。

補足頂きました。

 pBufferはファイルを丸ごと吸い上げた状態です。
 バッファ内のBITMAPINFO情報がある位置へ移動する為に、バッファの先頭からBITMAPFILEHEADERのサイズ分だけずらさなければいけません。

 ↓ファイル内の構造

 BITMAPFILEHEADER
 BITMAPINFOHEADER(BITMAPINFO::bmiHeader)//この位置に移動する為
 ある場合はカラーテーブル[1~255](BITMAPINFO::bmiColors[1~255])※配列は0を基準
 ビットイメージ
    • good
    • 0
この回答へのお礼

BITMAPINFO情報ある場所まで配列を移動させ、そこからカラーパレットの情報を読み上げるんですね。
 分かりました。 補足の回答ありがとうございます。
 ネットで調べてたんですがよく分からなかったんで質問してみました。答えてくれる人がいて助かりました。

お礼日時:2009/11/06 01:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!