4

バイトの BGRA 配列として格納されたビットマップがあります。これは、ビットマップを描画するために使用してきたコードです。

CDC *dispDC = new CDC();
dispDC->CreateCompatibleDC(pDC);
CBitmap *dispBMP = new CBitmap();
dispBMP->CreateCompatibleBitmap(pDC, sourceImage->GetWidth(), sourceImage->GetHeight());
dispDC->SelectObject(this->dispBMP);

配列内のピクセルの実際のコピーは、次のように行わtranslatedImageれます。

dispBMP->SetBitmapBits(sourceImage->GetArea() * 4, translatedImage);

次に、さらに処理を行った後、ソース CDC として呼び出しpDC->StretchBltますdispDC。ディスプレイも 32bpp に設定されているため、ローカルにログインすると問題なく動作します。

リモート デスクトップでログインすると、ディスプレイが 16bpp になり、画像が乱れます。犯人はSetBitmapBits; translatedImageつまり、それが機能するためには、表示したいものの 16bpp バージョンを適切に入力する必要があります。これを自分で行うのではなく、ドキュメントを検索して、SetDIBits私が望むように聞こえるものを見つけました。

SetDIBits 関数は、指定された DIB で見つかったカラー データを使用して、互換ビットマップ (DDB) にピクセルを設定します。

私の場合、DIB は 32bpp RGBA 配列で、DDB はdispBMPで作成したものCreateCompatibleBitmapです。

への呼び出しの代わりにSetBitmapBits、これが私がしたことです:

BITMAPINFO info;
ZeroMemory(&info, sizeof(BITMAPINFO));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = sourceImage->GetArea()*4;
info.bmiHeader.biWidth = sourceImage->GetWidth();
info.bmiHeader.biHeight = sourceImage->GetHeight();
info.bmiHeader.biClrUsed = 0;

int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
                  0, sourceImage->GetHeight(), translatedImage, 
                  &info, DIB_PAL_COLORS);

ただし、r常にゼロであり、当然、ウィンドウには何も表示されません。コードの何が問題になっていますか?

4

2 に答える 2

5

のドキュメントにSetDIBitsよると:

アプリケーションがこの関数を呼び出すときに、hbmp パラメーターで識別されるビットマップをデバイス コンテキストに選択してはなりません。

サンプルコードでは、作成後にデバイスコンテキストで選択するため、おそらくそれSetDIBitsが失敗する理由です。

于 2014-08-24T01:07:55.307 に答える
4

コードの順序の間違いを指摘した Ross Ridge は正しかった。ただし、これで問題は解決しませんでした。

問題は、渡していたパラメーターにありました。私は C++ と MFC に不慣れで、型に作用して自動的に変換できるすべての「演算子」を忘れがちです。

以前はこれを持っていました:

int r = SetDIBits(pDC->GetSafeHdc(), (HBITMAP)dispBMP,
              0, sourceImage->GetHeight(), translatedImage, 
              &info, DIB_PAL_COLORS);

正しい呼び出しは次のとおりです。

int r = SetDIBits(*pDC, *dispBMP,
              0, sourceImage->GetHeight(), translatedImage, 
              &info, DIB_PAL_COLORS);

DIB_PAL_COLORS(最初の 2 つのパラメーターで間接参照されたポインターを渡すことに注意してください。)パレットを持たないビットマップの直観に反するフラグを含め、他のすべては正しかったです。

ドキュメントのいくつかの重要なポイントを明らかに見逃していたので、それを読み直したところ、パラメーターを間違って渡していたことを示すサンプルコードが含まれていることがわかりました。

于 2014-09-02T15:37:59.830 に答える