Это ошибка в документации TransparentBlt()?

Вопрос или проблема

Документация Microsoft по функции GDI TransparentBlt() утверждает:

Функция TransparentBlt поддерживает все форматы исходных растровых изображений. Однако для растровых изображений с глубиной цвета 32 бита она просто копирует значение альфа-канала.

Это ошибка?

Код ниже противоречит этой документации, демонстрируя, что TransparentBlt() обнуляет значение альфа-канала для непрозрачного пикселя и не копирует никакие каналы исходного прозрачного пикселя вообще (как и должно):

#include <windows.h>

void foo(void)
{
    BITMAPINFO bmi = { {sizeof(BITMAPINFOHEADER), 2, 1,1,32,BI_RGB,0,0,0,0,0} };
    PDWORD PixelsSrc;
    HBITMAP hBmpSrc = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, reinterpret_cast<PVOID*>(&PixelsSrc), NULL, 0);
    PixelsSrc[0] = 0xEE555555; PixelsSrc[1] = 0xFFAAAAAA;

    PDWORD PixelsDst;
    HBITMAP hBmpDst = CreateDIBSection(0, &bmi, DIB_RGB_COLORS, reinterpret_cast<PVOID*>(&PixelsDst), NULL, 0);
    PixelsDst[0] = 0xCC222222; PixelsDst[1] = 0xDD333333;
    
    HDC hDCsrc = CreateCompatibleDC(NULL);
    HDC hDCdst = CreateCompatibleDC(NULL);
    SelectObject(hDCsrc, hBmpSrc);
    SelectObject(hDCdst, hBmpDst);
    printf("Src: %08X, %08X\n", PixelsSrc[0], PixelsSrc[1]);    
    printf("Dst: %08X, %08X\n", PixelsDst[0], PixelsDst[1]);
    TransparentBlt(hDCdst, 0, 0, 2, 1, hDCsrc, 0, 0, 2, 1, 0x00555555);
    printf("DST: %08X, %08X\n", PixelsDst[0], PixelsDst[1]);
}

Вывод:

Src: EE555555, FFAAAAAA
Dst: CC222222, DD333333
DST: CC222222, 00AAAAAA

Если бы значение альфа-канала для непрозрачного пикселя было скопировано, то вывод был бы следующим:

Src: EE555555, FFAAAAAA
Dst: CC222222, DD333333
DST: CC222222, FFAAAAAA

Примечание: альфа-канал закодирован в старшем бите данных пикселя (bigendian DWORD).

Ответ или решение

Вопрос о правильности документации функции TransparentBlt() в контексте ее работы с 32-битными битмапами требует детального рассмотрения. Согласно документации Microsoft, функция TransparentBlt() поддерживает все форматы исходных битмапов, однако для 32-битных битмапов "просто копирует значение альфа-канала". Этот вывод вызывает определенные сомнения, особенно в свете приведенного вами кода и результатов его выполнения.

Анализ кода и поведения TransparentBlt()

Приведенный код демонстрирует создание двух битмапов (источника и назначения) с 32-битной глубиной цвета, а также применение функции TransparentBlt() для копирования пикселей из исходного битмапа в битмап назначения с учетом прозрачности.

Ключевые моменты:

  1. Инициализация пикселей:

    • Пиксель 0xEE555555 в исходном битмапе имеет альфа-канал (первый байт) со значением EE, и RGB-значение 555555.
    • Пиксель 0xFFAAAAAA в исходном битмапе — полностью непрозрачный (альфа-канал FF), с RGB-значением AAAAAA.
    • В битмапе назначения инициализированы пиксели 0xCC222222 и 0xDD333333.
  2. Вызов TransparentBlt():

    • В вашем коде вызывается TransparentBlt() с аргументом 0x00555555, где 00 указывает на прозрачный цвет. По идее, при обработке функции, пиксель с альфа-каналом EE должен был бы скопироваться в пиксель назначения, а пиксель с альфа-каналом FF — оставить в исходном состоянии.
  3. Результаты выполнения:

    • После вызова функции TransparentBlt() вывод показывает, что альфа-канал для второго пикселя в битмапе назначения стал 00AAAAAA, что свидетельствует о том, что функция обнуляет альфа-канал для пикселей, которые не являются прозрачными, вместо того чтобы копировать значение из исходного битмапа.

Доказательство ошибки в документации

Ваши наблюдения подтверждают несоответствие между заявленной функциональностью в документации и фактическим поведением функции:

  • Документация утверждает, что альфа-канал копируется, что подразумевает, что пиксель, который не является прозрачным, должен сохранить свое значение альфа-канала. Однако, на практике, альфа-канал для пикселя с RGB AAAAAA изменился на 00.

Таким образом, можно сделать вывод о наличии ошибки в документации функции TransparentBlt(). Основной проблемой является несоответствие между тем, что было заявлено, и тем, что действительно происходит при вызове функции. Функция, по факту, не выполняет ожидаемую операцию копирования альфа-канала для непроводимых пикселей.

Заключение

Для программистов, работающих с Windows GDI и использующих функцию TransparentBlt(), важно знать о данной несоответствующей документации, чтобы избежать неожиданных результатов. Рекомендуется также обратиться в службу поддержки Microsoft с сообщением о данной проблеме, чтобы улучшить документы и восстановить соответствие между описанием и реальным поведением функции.

Оцените материал
Добавить комментарий

Капча загружается...