У меня есть растровое изображение 32bpp, которое имеет альфа-канал со значениями в диапазоне 0-255. Я пытаюсь отобразить это в окне с помощью Win32 API (добавлен фрагмент кода, который я использую для отображения).
Я читал документацию и оказалось, что для смешивания, в случае, когда я хочу использовать значения для каждого пикселя, Windows использует следующую формулу:
Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green
Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
Это странно Я бы ожидал, что он будет использовать:
Dst.Red = Src.Alpha*Src.Red + (1 - Src.Alpha) * Dst.Red
Dst.Green = Src.Alpha*Src.Green + (1 - Src.Alpha) * Dst.Green
Dst.Blue = Src.Alpha*Src.Blue + (1 - Src.Alpha) * Dst.Blue
потому что это то, что создает эффект наложения (прозрачность).
Верны ли мои ожидания? Если да, почему окна смешивают таким образом? Что мне здесь не хватает?
фрагмент кода, который я использую для рисования многослойного окна:
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
bf.AlphaFormat = AC_SRC_ALPHA;
POINT ptOrigin = { 0, 0 };
SIZE windowSize = { 300, 300 };
POINT ptZero = { 0, 0 };
UpdateLayeredWindow(m_sThis->m_hWnd, dc, &ptOrigin, &windowSize,
hdc, &ptZero, RGB(255, 255, 255), &bf, ULW_ALPHA);
От документация:
Обратите внимание, что API используют предварительно умноженную альфа, что означает, что красный,
Значения зеленого и синего каналов в растровом изображении должны быть предварительно умножены на
значение альфа-канала. Например, если значение альфа-канала равно x,
красный, зеленый и синий каналы должны быть умножены на х и разделены
на 0xff до звонка.
Итак, вы правы, но вы должны сделать это вручную.
Других решений пока нет …