PyGame: полупрозрачные спрайты с альфа-пикселем - PullRequest
13 голосов
/ 25 ноября 2010

Можно ли отображать поверхности PyGame с управляемой альфа? Я хотел бы взять поверхность со своей альфа-точкой на пиксель и отобразить ее с переменным уровнем прозрачности, не затрагивая данные поверхности, и сохранить прозрачность неизменной, т.е. объекты на поверхности сохранят свою форму, но их «содержимое» станет более или менее полупрозрачными.

Другими словами, я хочу объединить альфа на пиксель исходного изображения с альфа на каждую поверхность, рассчитанную во время выполнения.

Ответы [ 4 ]

7 голосов
/ 04 октября 2015

В документации Pygame говорится, что вы не можете комбинировать поверхностную альфа с альфа-версией на пиксель, но если вы используете Pygame 1.8.1 или новее, вы можете обойти это, используя special_flags параметр для .blit().

Вот как я это сделал:

# Load an image with per-pixel alpha
s = pygame.image.load('spam.png')
s.convert_alpha()

# Simulate s.set_alpha(alpha)
alpha_img = pygame.Surface(s.get_rect().size, pygame.SRCALPHA)
alpha_img.fill((255, 255, 255, alpha))
s.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)

Способ, которым это работает, состоит в том, чтобы создать вторую поверхность того же размера, что и первая, и добавить ее кпервое использование RGBA умножение .Если компоненты R, G и B второго изображения равны 255, умножение не повлияет на цвет изображения, но оно будет масштабировать альфа-канал с учетом заданного альфа-фактора.

Обратите внимание, чтоописанный выше метод отличается от вызова set_alpha() тем, что set_alpha() можно изменить, вызвав set_alpha(255).Если вы воспользуетесь описанным выше способом, это приведет к изменению альфа-пикселя каждого пикселя, поэтому процесс не может быть полностью изменен.

4 голосов
/ 27 декабря 2010

После проверки документации PyGame и SDL я пришел к выводу, что то, о чем я просил, невозможно выполнить в PyGame с использованием стандартных функций.

Документы SDL утверждают, что альфа на пиксель и альфа на поверхность не могут быть объединены с первым, всегда имеющим приоритет. Единственный способ добиться желаемого эффекта - написать код, который обновляет альфа-значения на пиксель поверхности источника перед блитом.

4 голосов
/ 25 ноября 2010

Да, вы можете.Документация класса Surface объясняет, как это сделать.Это сводится только к двум случаям: либо вы устанавливаете флаг во время создания объекта Surface:

s = pygame.Surface((16, 16), flags=pygame.SRCALPHA)

, либо вы отдаете альфа-канал поверхности, у которой его еще нет:

s = pygame.image.load('spam.png')
s.convert_alpha()

В документации модуля pygame.image говорится, что применение convert_alpha необходимо для PNG с прозрачностью.

Если вы хотите, вы можете изменить альфа-значение каждого пикселя с помощью модулей draw и surfarray.При указании цвета используйте кортеж из четырех целых чисел: (красный, зеленый, синий, альфа).Параметр альфа варьируется от 0 (полностью прозрачный) до 255 (полностью непрозрачный).

import pygame
pygame.init()
screen = pygame.display.set_mode((320, 200))
screen.fill((200, 100, 200))
s = pygame.Surface((64, 64), flags=pygame.SRCALPHA)
for i in range(64):
    pygame.draw.line(s, (0, 0, 0, i*4), (0, i), (64, i))

screen.blit(s, (50, 30))
pygame.display.flip()
1 голос
/ 10 сентября 2012

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

Это быстрая и грязная вспомогательная функция, которую я использовал для затухания текстовых эффектов и других вещей:

def convert_to_colorkey_alpha(surf, colorkey=pygame.color.Color("magenta")):
    newsurf = surface.Surface(surf.get_size())
    newsurf.fill(colorkey)
    newsurf.blit(surf, (0, 0))
    newsurf.set_colorkey(colorkey)
    return newsurf

Несколько других трюков могут решить эту проблему:

  • Выполнение редактирования по пикселям для изменения альфа-канала перед блиттингом
  • Размытие белой или черной, полупрозрачной поверхности с помощью special_flags = BLEND_RGBA_MULT или BLEND_RGBA_SUB на поверхность источника.
...