BitBlt从ClipBoard复制位图给出错误的颜色

时间:2012-10-16 15:34:45

标签: c++ winapi palette bitblt

我将剪贴板中的图像粘贴到我的程序中。位图放在后台memDC位图上,然后在绘制到屏幕之前将其与另一个memDC合成。背景位图是每像素8位。问题是bitblt将Black(0x00000000)变为Almost-Black(0x00010101)。如果我将相同的东西粘贴到MSPaint中,我会得到黑色。如果我从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生成的几乎黑色。

其他程序似乎没有在调色板上放置调色板 - 也许是因为他们正在放置不需要调色板的32bpp位图?他们甚至没有根据MSDN's clipboard translation table

查看可用的DIB数据。

1 个答案:

答案 0 :(得分:3)

每像素8位位图需要一个相关的调色板来指定颜色,这是独立的 - 您可以使用CF_PALETTE从剪贴板中获取颜色。完成后,在选择位图的DC上使用SelectPaletteRealizePalette