Pygame и блитирование: белый на белом = серый?

Мы всегда используем эти OBJECT_ID стиль столько, сколько я помню

IF OBJECT_ID('*objectName*', 'U') IS NOT NULL 
5
задан Ron Eggbertson 21 July 2009 в 06:41
поделиться

2 ответа

Попробовав, единственное, что я смог увидеть, это то, что вы на 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. Игнорируйте его, потому что для большинства целей нет значения "отключаемое".
  2. Добавьте 1 ко всем значениям результатов. Самый близкий к ожидаемому результат, за исключением того, что вы теряете ноль.
  3. Если общая правильность не важна, но вам нужно 255 * 255 == 255 (вы понимаете, о чем я), ORing 1 вместо добавления достаточных значений и работает быстрее.

Обратите внимание, что если вы не выберете ответ 1, по соображениям производительности вам, вероятно, придется написать расширение C вместо прямого использования Python.

6
ответ дан 14 December 2019 в 08:57
поделиться

Также столкнулся с этой проблемой при создании тепловых карт, и после прочтения ответа balpha решил исправить ее "правильным" (если медленнее) способом. Измените различные

(s * d) >> 8

на

(s * d) / 255 

. Это потребовало исправления функций умножения в alphablit.c (хотя я также исправил surface.h ). Не уверен, насколько это влияет на производительность, но для конкретного приложения (тепловая карта) оно дает гораздо более красивые изображения.

1
ответ дан 14 December 2019 в 08:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: