2

現在、古い GDI コードを編集して GDI+ を使用していますが、背景が透明な BMP ファイルを描画するときに問題が発生しました。古いGDIコードは、背景を透明にするために明らかな余分なコードを使用していなかったので、GDI +を使用してこれを実現する方法を考えています。

私の現在のコードは次のようになります

HINSTANCE hinstance = GetModuleHandle(NULL);
bmp = Gdiplus::Bitmap::FromResource(hinstance, MAKEINTRESOURCEW(IDB_BMP));
Gdiplus::Graphics graphics(pDC->m_hDC);
graphics.DrawImage(&bmp, posX, posY);

また、クローン メソッドを使用してリソースから新しいビットマップを作成し、ビットマップを新しく作成したビットマップに描画しようとしましたが、どちらも役に立ちませんでした。どちらの場合も、PixelFormat32bppPARGB を使用しました。

次に、アルファブレンディングを使用しようとしましたが、この方法では背景だけでなく画像全体が透明になります。

Gdiplus::ColorMatrix clrMatrix = { 
    1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.5f, 0.0f,
    0.0f, 0.0f, 0.0f, 0.0f, 1.0f
};

Gdiplus::ImageAttributes imgAttr;
imgAttr.SetColorMatrix(&clrMatrix);

graphics.DrawImage(&bmp, destRect, 0, 0, width(), height(), Gdiplus::UnitPixel, &imgAttr);

透明度情報は既に画像に含まれていますが、画像を描画するときにそれを適用する方法がわかりません。どうすればこれを達成できますか?

4

3 に答える 3

2

遅い答えですが:

ImageAttributes imAtt;    
imAtt.SetColorKey(Color(255,255,255), Color(255,255,255), ColorAdjustTypeBitmap);  

この画像属性を使用するビットマップをwhite (255,255,255)透明にします。

于 2015-06-09T00:15:19.567 に答える
1

最も簡単な解決策は、BMP 以外の形式を使用することです。

ビットにアルファ データを含める必要があり、ビットマップがアルファ データを含む形式である必要があります。GDI+ で BMP をロードすると、BMP にアルファ チャネルがある場合でも、常にアルファなしの形式が使用されます。データは画像ビットにあると思いますが、使用されていません。

PixelFormat32bppPARGB ビットマップに複製または描画するときの問題は、GDI+ が画像データを新しい形式に変換することです。これは、アルファ データを破棄することを意味します。

ビットが正しくロードされていると仮定すると、ビットを正しい形式で別のビットマップに直接コピーする必要があります。Bitmap::LockBitsBitmap:: UnlockBits でこれを行うことができます。(変換が行われないように、各ビットマップをネイティブのピクセル形式でロックしてください。)

于 2012-07-28T01:32:16.123 に答える
0

私も同じ問題を抱えていました。透明な BMP は正しく表示されておらず、残念ながら、PNG をリソースから直接ロードすることはできません (ただし、PNG をストリームにコピーしてストリームからロードするかなりの量のコードを追加する必要があります)。このコードは避けたかった。
私が使用しているビットマップも、2 色 (背景とロゴ) のみを使用しています。アルファ チャネルがあるということは、2 ビットの色深度だけではなく、はるかに高い色深度でそれらを保存する必要があることを意味します。

エヴァンの答えはまさに私が探していたものでした:-)

白の代わりに、左上のピクセルの色を透明色として使用しています。

Gdiplus::Color ColourOfTopLeftPixel;
Gdiplus::Status eStatus = m_pBitmap->GetPixel(0, 0, &ColourOfTopLeftPixel);
_ASSERTE(eStatus == Gdiplus::Ok);

// The following makes every pixel with the same colour as the top left pixel (ColourOfTopLeftPixel) transparent.
Gdiplus::ImageAttributes ImgAtt;
ImgAtt.SetColorKey(ColourOfTopLeftPixel, ColourOfTopLeftPixel, Gdiplus::ColorAdjustTypeBitmap);
于 2015-10-08T07:24:55.050 に答える