• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Win32でのBITMAP)

Win32でのBITMAPの色情報取得方法について

このQ&Aのポイント
  • BITMAPをバイナリデータから作成する際の色情報取得方法について質問があります。
  • BITMAPのbiBitcountに基づいてカラーテーブルの色情報を取得する方法を試していますが、8Bit(256色)の場合に正しく動作するか疑問です。
  • また、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; }

dotneer
質問者

お礼

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

dotneer
質問者

補足

 実はまだBITMAP構造には疑問を持っているところがあり、全てを把握してないせいか上記でのソースで理解できないところがあるので質問なんですが、 BITMAPINFO* pbmpInfo = reinterpret_cast<BITMAPINFO*>(&pBuffer[sizeof(BITMAPFILEHEADER)]); でLPBYTEのアドレスを渡しているのですが、何故sizeof(BITMAPFILEHEADER)]);なんですか?pBufferの大きさはファイルサイズ分ですよね?

その他の回答 (1)

回答No.2

 こんばんは。補足頂きました。  pBufferはファイルを丸ごと吸い上げた状態です。  バッファ内のBITMAPINFO情報がある位置へ移動する為に、バッファの先頭からBITMAPFILEHEADERのサイズ分だけずらさなければいけません。  ↓ファイル内の構造  BITMAPFILEHEADER  BITMAPINFOHEADER(BITMAPINFO::bmiHeader)//この位置に移動する為  ある場合はカラーテーブル[1~255](BITMAPINFO::bmiColors[1~255])※配列は0を基準  ビットイメージ

dotneer
質問者

お礼

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

関連するQ&A