Мы всегда используем эти OBJECT_ID
стиль столько, сколько я помню
IF OBJECT_ID('*objectName*', 'U') IS NOT NULL
Попробовав, единственное, что я смог увидеть, это то, что вы на 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 / 256
, что было бы правильным способом, as
new_val = old_dest * old_source / 255
Вероятно, это сделано в целях оптимизации - битовый сдвиг намного быстрее, чем деление. Поскольку отношение 255/256
очень близко к единице, единственное отличие, которое это дает, - это «на единицу меньше»: значение, которое вы получаете, - это ожидаемое значение минус один - за исключением случаев, когда вы ожидали ноль, в в этом случае результат правильный.
Итак, у вас есть следующие возможности:
1
ко всем значениям результатов. Самый близкий к ожидаемому результат, за исключением того, что вы теряете ноль. 255 * 255 == 255
(вы понимаете, о чем я), ORing 1
вместо добавления достаточных значений и работает быстрее. Обратите внимание, что если вы не выберете ответ 1, по соображениям производительности вам, вероятно, придется написать расширение C вместо прямого использования Python.
Также столкнулся с этой проблемой при создании тепловых карт, и после прочтения ответа balpha решил исправить ее "правильным" (если медленнее) способом. Измените различные
(s * d) >> 8
на
(s * d) / 255
. Это потребовало исправления функций умножения в alphablit.c
(хотя я также исправил surface.h
). Не уверен, насколько это влияет на производительность, но для конкретного приложения (тепловая карта) оно дает гораздо более красивые изображения.