BitBlt Copy Bitmap из ClipBoard дает неправильные цвета

Я вставляю изображение из буфера обмена в мою программу. Растровое изображение помещается в фоновое растровое изображение memDC, которое затем комбинируется с другим memDC перед выводом на экран. Фоновое растровое изображение составляет 8 бит на пиксель. Проблема в том, что битовый бит превращает черный (0x00000000) в почти черный (0x00010101). Если я вставлю то же самое в MSPaint, я получу Black. Если я копирую Black из MSPaint, я получаю почти 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, которые не нуждаются в палитре? Они даже не делают DIB настолько близко, насколько я могу судить, глядя на то, что доступно на основе таблицы перевода буфера обмена MSDN.

1 ответ

Растровое изображение размером 8 бит на пиксель нуждается в соответствующей палитре для указания цветов, которая является отдельной - вы получаете ее из буфера обмена, используя CF_PALETTE, Как только у вас это есть, вы используете SelectPalette а также RealizePalette на DC, в который выбрано растровое изображение.

Другие вопросы по тегам