Попробовав, единственное, что я увидел, было то, что ты на 100% прав. Умножение на 255 приводит к вычитанию 1 - каждый раз. В конце концов, я скачал исходный код Pygame, и ответ тут же, в surface.h
:
#define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
dB = (dB && sB) ? (dB * sB) >> 8 : 0;
Pygame реализует многократное смешивание как
new_val = old_dest * old_source / 256
и нет, что было бы правильным путем, как
new_val = old_dest * old_source / 255
Это, вероятно, сделано в целях оптимизации - сдвиг бит намного быстрее, чем деление. Поскольку отношение 255 / 256
очень близко к единице, единственное отличие, которое это делает, - это «выключено на единицу»: получаемое вами значение - это ожидаемое значение минус один - кроме случаев, когда вы ожидали ноль, в этом случае результат будет правильным .
Итак, у вас есть следующие возможности:
- Не обращайте на это внимания, потому что для большинства целей одно за другим не имеет значения.
- Добавить
1
ко всем значениям результата. Ближайший к ожидаемому результату, за исключением того, что вы теряете ноль.
- Если общая корректность не важна, но вам нужно
255 * 255 == 255
(вы понимаете, о чем я), вместо добавления достаточно ИЛИ 1
, и это быстрее.
Обратите внимание, что если вы не выберете ответ 1, по соображениям производительности вам, вероятно, придется написать расширение C вместо непосредственного использования Python.