本ページは公開が終了した情報の複製であり、掲載時点での情報です。本ページに記載されている内容について各所に問い合わせることはご遠慮下さい。
サポート技術情報

[VC40] リソースから256色のビットマップを読み込む方法

文書番号: 403836

最終更新日: 2004/04/27


この資料は以下の製品について記述したものです。


概要

この資料は、MFC によりリソース から DIB ビットマップ (256 色のビットマップ) を 読みだし View に表示する一つの方法を紹介したものです。

詳細

システムが 256 色表示の場合、リソースに登録されている 256 色のビットマップ
(DIB ビットマップ)を LoadBitmap 関数で読み込むと、予約されている 20 色の
システムカラーで描画されてしまいます。
これは LoadBitmap 関数が DIB ビットマップを DDB ビットマップに変換する際に
カラー情報が失われるためです。カラー情報が必要な場合は FindResource、
LoadResource、LockResource などの関数を利用してビットマップヘッダから
カラー情報を取り出す必要があります。
ビットマップデータをメモリデバイスへ転送後 View に表示する場合、
SetDIBitsToDevice 関数を使用すると正しく表示されません。
これは SetDIBitsToDevice 関数が表示可能なデバイスに対してしか動作保証をして
いないためです。メモリデバイスに転送する場合には StretchDIBits 関数か
SetDIBits 関数を使用してください。

サンプルコード

このサンプルはリソースに登録されたビットマップ (IDB_BITMAP1 640X480 256 色)
を View に表示します。
  /////////////////////////////////////////////////////////////////////////////
  class CMy256BitMapLoadView : public CView
  {
  • ・・
      public:
          CBitmap*    MyBitmap;
          CDC*        MemDC;
          CPalette*   MyPalette;
          BOOL        CopyDIB( CDC* pDC );
    
  • ・・
      }
      /////////////////////////////////////////////////////////////////////////////
      //  メモリデバイスの作成とメモリデバイスから表示デバイス (View) への転送を行う
      void CMy256BitMapLoadView::OnDraw(CDC* pDC)
      {
          CMy256BitMapLoadDoc* pDoc = GetDocument();
          ASSERT_VALID(pDoc);
          MyPalette   = new CPalette;
          MyBitmap    = new CBitmap;
          MemDC       = new CDC;
          MemDC->CreateCompatibleDC( pDC );
          MyBitmap->CreateCompatibleBitmap( pDC, 640, 480 );
          MemDC->SelectObject( MyBitmap );
          // メモリデバイスコンテキストにリソースからビットマップを転送
          CopyDIB( MemDC );
          // 表示用のパレットを前景パレットで設定
          CPalette* oldPalette;
          oldPalette = pDC->SelectPalette( MyPalette,FALSE );
          UINT ret   = pDC->RealizePalette();
          // 残りのパレットは背景パレットで設定
          pDC->SelectPalette( oldPalette,TRUE );
          // メモリデバイスコンテキストから View にビットマップを転送
          pDC->BitBlt( 0,0, 640, 480, MemDC, 0,0, SRCCOPY );
          delete    MyPalette;
          delete    MyBitmap;
          delete    MemDC;
      }
      /////////////////////////////////////////////////////////////////////////////
      //  リソースをロックし BITMAP 構造体を保持するメモリハンドルを確保し
      //  必要なデータ (パレット情報やピクセル情報) を読み出す
      BOOL CMy256BitMapLoadView::CopyDIB( CDC* pDC )
      {
          // リソースからパレットデータを読み込み論理パレットを作成
          LPBITMAPINFO    lpBitmapInfo;   // BITMAPINFO 構造体へのポインタ
          LPLOGPALETTE    lpPal;          // LOGPALETTE 構造体へのポインタ
          HANDLE          hLogPal;        // 論理パレットへのハンドル
          WORD            nNumColors;     // パレットエントリ
          // リソースをロードしハンドルをロック
          HANDLE    hRes = ::LoadResource( AfxGetApp()->m_hInstance,
                           ::FindResource( AfxGetApp()->m_hInstance,
                           MAKEINTRESOURCE( IDB_BITMAP1 ),RT_BITMAP) );
          lpBitmapInfo = (LPBITMAPINFO)::LockResource( hRes );
          // カラーエントリ数を計算
          if ( lpBitmapInfo->bmiHeader.biClrUsed != 0 )
              nNumColors = (WORD)lpBitmapInfo->bmiHeader.biClrUsed;
          else {
              switch( lpBitmapInfo->bmiHeader.biBitCount ){
                  case 1:
                      nNumColors = 2;     // モノクロ
                      break;
                  case 4:
                      nNumColors = 16;    // VGA
                      break;
                  case 8:
                      nNumColors = 256;    // 256 Color
                      break;
                  case 24:
                      nNumColors = 0;
                      break;
              }
          }
          hLogPal = ::GlobalAlloc( GMEM_DISCARDABLE,
                  sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColors );
          lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal );
          // バージョンとパレットへのエントリ数を設定
          lpPal->palVersion = 0x300;
          lpPal->palNumEntries = nNumColors;
          for ( int i = 0; i < (int)nNumColors; i++ ){
              lpPal->palPalEntry[i].peRed   =
                          lpBitmapInfo->bmiColors[i].rgbRed;
              lpPal->palPalEntry[i].peGreen =
                          lpBitmapInfo->bmiColors[i].rgbGreen;
              lpPal->palPalEntry[i].peBlue  =
                          lpBitmapInfo->bmiColors[i].rgbBlue;
              lpPal->palPalEntry[i].peFlags = 0;
          }
          // 論理パレットを作成
          MyPalette->CreatePalette( lpPal );
          ::GlobalUnlock((HGLOBAL) hLogPal);
          ::GlobalFree((HGLOBAL) hLogPal);
          pDC->SelectPalette( MyPalette,FALSE );
          pDC->RealizePalette();
          // ピクセルデータの位置を計算
          LPBYTE    lpvBits = (LPBYTE)lpBitmapInfo+ lpBitmapInfo->bmiHeader.biSize
                                               + sizeof(RGBQUAD) * nNumColors;
          // SetDIBitsToDevice は使わない
          int ret = ::StretchDIBits(
                      pDC->m_hDC,             // デバイスコンテキストのハンドル
                      0,0,                    // 転送先のアドレス
                      (int)(lpBitmapInfo->bmiHeader.biWidth),     // 幅
                      (int)(lpBitmapInfo->bmiHeader.biHeight),    // 高さ
                      0,0,                    // 転送元の アドレス
                      (int)(lpBitmapInfo->bmiHeader.biWidth),     // 幅
                      (int)(lpBitmapInfo->bmiHeader.biHeight),    // 高さ
                      lpvBits,                // DIB ビット の配列のアドレス
                      lpBitmapInfo,           // ビットマップ情報のアドレス
                      DIB_RGB_COLORS,         // RGB 値
                      SRCCOPY                 // ラスタオペレーション
                      );
          return 0;
      }
    

関連情報

MFC Sample

  Visual C++ 付属のサンプル DIBLOOK

Appnote


401949 [MSVC] MFC でパレットを使ったサンプル

詳細

  • Visual C++ は、米国 Microsoft Corporation の登録商標です。

Keywords: BITMAPINFOHEADER KBHOWTO VC10 VC15 VC20 VC40 VC41 VC42 VC4x VC50 KB403836
Technology: kbAudDeveloper kbVC32bitSearch kbVC400 kbVCsearch

inserted by FC2 system