BITMAPFILEHEADER BITMAPINFOHEADER RGBQUADの配列 イメージ本体を格納したバイト列のような構造になっています。それぞれの内容をさらに詳しく見ると
typedef struct tagBITMAPFILEHEADER { WORD bfType; /*ファイル種別 'BM' */ DWORD bfSize; /*ファイルサイズ*/ WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; /*ファイル先頭からイメージ本体までのオフセット*/ } BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER { /* bmih */ DWORD biSize; /*この構造体のサイズ*/ LONG biWidth; /*幅(ドット数)*/ LONG biHeight;/*高さ(ドット数)*/ WORD biPlanes;/*必ず1*/ WORD biBitCount;/*ピクセル当たりのビット数 1,2,4,8,16,24,32*/ DWORD biCompression;/*圧縮タイプ BI_RGBなら無圧縮*/ DWORD biSizeImage;/*イメージ本体のサイズ*/ LONG biXPelsPerMeter;/*水平解像度 0で良い*/ LONG biYPelsPerMeter;/*垂直解像度 0で良い*/ DWORD biClrUsed;/*使われている色の数*/ DWORD biClrImportant;/*重要な色の数*/ } BITMAPINFOHEADER;
typedef struct tagRGBQUAD { /* rgbq */ BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD;これはパレット情報です。16ビットや24ビットや32ビットのbmpには存在しません。 8ビット以下のBMPファイルには、その色数ぶんのエントリが存在します。
イメージ本体
1ヒットから32ビットまで種類がありますが、要するに実際のイメージがベタで記録されます。(無圧縮の場合)
ただし、一ラインごとに32ビット境界に合わせて「つめもの」がつめられます。
では実際に作ってみます。 「bmpv」の全ソース
ソースに従って、処理内容を解説してみます。
また、今回は使いませんでしたが、プログラム中でビットマップデータを直接 操作するためには、hugeなポインタを宣言してこれを使う必要があります。 メモリ操作関数もC標準のmemset()やmemcpy()は使えなくなります。
32ビットの場合は単純にmalloc()等を使えば良いのですが、ソース共通にするために #ifdefで切り換えています。
hdc=GetDC(hDlg); hMemDC = CreateCompatibleDC(hdc); /* メモリDCを作成 */ hDDBitmap = CreateCompatibleBitmap(hdc, lpbi->biWidth, lpbi->biHeight);/*DDBを作成*/ /* 作成したDDBをDIBにあわせて設定、走査線のコピーも行う */ SetDIBits(hdc, hDDBitmap, 0, lpbi->biHeight, (LPSTR)lpbi+offBits, lpbi, DIB_RGB_COLORS); hOldBitmap = (HBITMAP)SelectObject(hMemDC, hDDBitmap);/*メモリDCにDDBを選択させる*/ ReleaseDC(hDlg, hdc);のようにDDBを作成しDIBの内容を転送します。前回説明したDDBの作成に、SetDIBits()が加わりました。 (順序を間違えないように。SelectObjectの前にSetDIBits()します)
表示は、前回と同じです。StretchBits()を使えば拡大/縮小もできます。
case WM_PAINT: hdc = BeginPaint(hDlg, &ps); BitBlt(hdc, 0, 0, lpbi->biWidth, lpbi->biHeight, hMemDC, 0, 0, SRCCOPY); EndPaint(hDlg, &ps);もちろん、必要なくなったら削除します。
SelectObject(hMemDC, hOldBitmap); DeleteDC(hMemDC); DeleteObject(hDDBitmap);これを新たなBMPを読み込むたびにやる必要があります。
ところで、今回作ったBMPビュアーには、まずい点が二点ほどあります。 まず、画面モードが256色モードで色がおかしくなる点(パレットを考慮していない)。 次に、BMPがウィンドウサイズをはみ出してもスクロールもしない点です。 これらの欠点の改善は、そのうち気が向いたらやるかもしれません。
一つ上のページに戻る