3

hbitmap オブジェクトに透明度を追加しようとしていますが、何も描画されません:/

これは、ハンドルを描画するために使用するコードです

HDC hdcMem = CreateCompatibleDC(hDC);
    HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, m_hBitmap);

    BLENDFUNCTION blender = {AC_SRC_OVER, 0, (int) (2.55 * 100), AC_SRC_ALPHA}; // blend function combines opacity and pixel based transparency
    AlphaBlend(hDC, x, y, rect.right - rect.left, rect.bottom - rect.top, hdcMem, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, blender);

    SelectObject(hdcMem, hbmOld);
    DeleteDC(hdcMem);

これは、hbitmap にアルファ チャネルを追加するコードです。

BITMAPINFOHEADER bminfoheader;
    ::ZeroMemory(&bminfoheader, sizeof(BITMAPINFOHEADER));
    bminfoheader.biSize        = sizeof(BITMAPINFOHEADER);
    bminfoheader.biWidth       = m_ResX;
    bminfoheader.biHeight      = m_ResY;
    bminfoheader.biPlanes      = 1;
    bminfoheader.biBitCount    = 32;
    bminfoheader.biCompression = BI_RGB;

    HDC windowDC = CreateCompatibleDC(0);
    unsigned char* pPixels = new unsigned char[m_ResX * m_ResY * 4];

    GetDIBits(windowDC, m_hBitmap, 0, m_ResY, pPixels, (BITMAPINFO*) &bminfoheader, DIB_RGB_COLORS); // load pixel info

    // add alpha channel values of 255 for every pixel if bmp
    for (int count = 0; count < m_ResX * m_ResY; count++)
    {
        pPixels[count * 4 + 3] = 255; <----  here i've tried to change the value to test different transparency, but it doesn't change anything
    }
    SetDIBits(windowDC, m_hBitmap, 0, GetHeight(), pPixels, (BITMAPINFO*) &bminfoheader, DIB_RGB_COLORS); // save the pixel info for later manipulation

    DeleteDC(windowDC);

編集:

これは、後でいくつかのコードでピクセルデータを入力するビットマップを作成する方法のコードです

m_hBuffer = CreateBitmap( m_ResX, m_ResY, 1, 32, nullptr );
4

1 に答える 1

3

これは楽しいものです!

これが何を出力すると思いますか?

#include <stdio.h>

int main()
{
    printf("%d\n", (int) (2.55 * 100));
    return 0;
}

回答: 254 - 255 ではありません。ここで 2 つのことが起こっています。

  • 浮動小数点数はしばしば不正確です - 2.55 は 2.55 を正確に表すバイナリ値で表されません - おそらく 2.5499963 のようなものです... 2 の分数 - 2 進数は 2 を底とするため - .5 や .25 のようなものは正確に表現できる可能性がありますが、他のほとんどの数値は近似値として表現されます. 浮動小数点出力ルーチンは逆に変換されるため、通常はこれに気づきません.これにより、本質的に別の不正確さが導入され、最初の不正確さが相殺されます。したがって、割り当てられた値または出力された値として表示されるものは、メモリに保存されている表現の値と正確には一致しません)。

  • int へのキャストは切り捨てます。つまり、切り捨てます。

これらをまとめると、(2.55 * 100) は 255 ではなく 254 になります。ピクセルごとのアルファを機能させるには、魔法の値 255 が必要です。

したがって、ここでの教訓は、純粋な整数に固執することです。または、浮動小数点から整数に変換する必要がある場合は、何が起こっているのかを認識して回避してください (たとえば、.5 を追加してから切り捨てる - または同様の手法を使用します)。

ところで、これは、コードを 1 行ずつステップ実行し、各ステップですべての入力と出力をチェックすることで問題が発生した可能性があるケースの 1 つです (デバッグするときは、偏執的になりすぎてはいけません!)。AlphaBlend に入る直前に、そのパラメーターにカーソルを合わせると 254 が表示され (DevStudio または同様のエディターを使用していると仮定)、何かが起きていることに気付くはずです。

于 2011-11-20T10:59:19.417 に答える