0

クリップボードからプログラムに画像を貼り付けています。ビットマップはバックグラウンド memDC ビットマップに配置され、画面に描画される前に別の memDC と合成されます。バックグラウンド ビットマップは、1 ピクセルあたり 8 ビットです。問題は、bitblt が Black (0x00000000) を Most-Black (0x00010101) に変えることです。同じものを MSPaint に貼り付けると、Black になります。MSPaint から Black をコピーすると、Almost Black が得られます。(他の色もバラバラです)。背景のビットマップを 32bpp に変更すると、正しい色が得られますが、現時点ではオプションではありません。

以下は、この問題を示すコードです。

/*
 *HWND hWnd; // main window handle
 *HDC hDC; // main window DC (set elsewhere)
 *HDC memDC; // background DC (set elsewhere)
 */
HBITMAP hClipBitmap=NULL;
OpenClipboard(hWnd);

hClipBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
if (hClipBitmap!=NULL)
{
    // I now want to make a copy of the bitmap
    BITMAP bm;
    HDC hSrcDC,hDestDC;
    HANDLE OldObject1, OldObject2;
    DWORD sz = GetObject(hClipBitmap, sizeof(BITMAP), &bm);
    if(sz == sizeof(BITMAP))
    {
            // make a bitmap to allow positioning before actual pasting
        hPasteBitmap = ::CreateCompatibleBitmap(memDC, bm.bmWidth, bm.bmHeight); 
        if (hPasteBitmap==NULL)
            FATAL_ERROR;
        hSrcDC = CreateCompatibleDC(hDC);
        hDestDC = CreateCompatibleDC(hDC);
        OldObject1 = SelectObject(hSrcDC, hClipBitmap); // bpp is 32
        OldObject2 = SelectObject(hDestDC, hPasteBitmap); // bpp is 8
        BitBlt(hDestDC, 0, 0, bm.bmWidth, bm.bmHeight, hSrcDC, 0, 0, SRCCOPY);
        COLORREF color2 = ::GetPixel(hSrcDC, 1, 1); // color2 is 0x00000000
        COLORREF color3 = ::GetPixel(hDestDC, 1, 1);// color2 is 0x00010101
        COLORREF color4 = ::GetNearestColor(hSrcDC, color2); //  0x00000000
        COLORREF color5 = ::GetNearestColor(hDestDC, color2);//  0x00000000
        // hPasteBitmap now contains the clipboard data
    }
}
// other cleanup snipped for clarity

GetPixel() と GetNearestColor() を使用すると、探している結果が得られるはずですが、そうではありません。ある種のパレット操作が欠けていると思いますか?

アップデート

私が本当に問題を抱えている部分は、これらの API のポイントを誤解している可能性がありますが、ピクセルの色を照会し、そのために使用する色をコンテキストに尋ねると、正しい色 (黒) が返されることです。 BitBltが生成するAlmost Blackの代わりに。

他のプログラムはクリップボードにパレットを置かないようです - おそらくパレットを必要としない 32bpp ビットマップを置いているからでしょうか? 彼らは、 MSDN のクリップボード変換テーブルに基づいて利用可能なものを見てわかる限り、DIB を行っていません。

4

1 に答える 1

3

1 ピクセルあたり 8 ビットのビットマップには、色を指定するための関連付けられたパレットが必要です。これは別のものです - を使用してクリップボードから取得しますCF_PALETTE。取得したら、ビットマップが選択されている DC で使用SelectPaletteします。RealizePalette

于 2012-10-16T22:36:34.447 に答える