Pygame, установите прозрачность изображения, импортированного с помощью convert alpha()
в моей игре pygame для импорта изображения jpeg я использую convert()
http://www.pygame.org/docs/ref/surface.html#pygame.Surface.convert
затем, чтобы играть с прозрачностью изображения (сколько мы можем видеть через изображение), я использую set_alpha()
http://www.pygame.org/docs/ref/surface.html#pygame.Surface.set_alpha
однако, чтобы импортировать мое png-изображение, которое имеет прозрачный фон, я использую convert_alpha()
http://www.pygame.org/docs/ref/surface.html#pygame.Surface.convert_alpha
но с этим способом импорта я не могу играть с общей прозрачностью, используя set_alpha()
. Любая другая идея настроить прозрачность (сколько мы видим через изображение)?
4 ответов
когда вы читаете документацию для set_alpha вы можете прочитать это : если формат поверхности содержит Альфы на пиксель, то это альфа-значение будет проигнорировано.
%в вашем случае, с изображением png, это Альфы на пиксель. Итак, вы должны управлять Альфой "на пиксель". Например, вы можете сделать это (не лучший код, но его легко понять. Работа с png только с прозрачностью no/yes):
def change_alpha(img,alpha=255):
width,height=img.get_size()
for x in range(0,width):
for y in range(0,height):
r,g,b,old_alpha=img.get_at((x,y))
if old_alpha>0:
img.set_at((x,y),(r,g,b,alpha))
будьте осторожны, это "медленно", потому что вы управляйте каждым пикселем, который не равен 0 (прозрачный из вашего png). Если ваш png имеет несколько уровней прозрачности, вы должны управлять прозрачностью с лучшей формулой, например:
r,g,b,old_alpha=img.get_at((x,y))
img.set_at((x,y),(r,g,b,(alpha*old_alpha)/255))
и в этом случае никогда не изменяйте исходное изображение, но работайте над копией, чтобы никогда не потерять свою оригинальную Альфу.
надеюсь, это поможет
===================== изменить =================== Добавьте некоторую оптимизацию, потому что спросите в комментарии
С методология кэширования:
class image_with_alpha(object):
def __init__(self,name=None):
self.img=None
self.alpha={}
if name:
self.load_image(name)
def load_image(self,name):
self.img=pygame.image.load(name)
self.alpha[255]=self.img
#self.pre_compute_alpha()
def pre_compute_alpha(self):
for alpha in range(0,10):
self.alpha[alpha]=change_alpha(self.img,alpha)
def get_img(self,a=255):
try:
return self.alpha[a]
except:
self.alpha[a]=change_alpha(self.img,a)
return self.alpha[a]
и используйте его так : Загрузить изображение:
image=image_with_alpha("test.png")
Блит с 60 для Альфы:
screen.blit(image.get_img(60),(0,0))
и теперь, я надеюсь, это быстро
самое быстрое решение, вероятно, использовать numpy
Array manipulation, он должен быть достаточно быстрым, чтобы избежать необходимости кэширования. Что действительно медленно в вычислении Альфа-значения по пикселям, это итерация в Python, в то время как numpy
все это в с.
начните с ссылки на альфа-канал изображения в numpy
массив. Это создаст блокировку на поверхности изображения; давайте вспомним об этом позже. Затем возьмите минимум (по пикселям) вашей исходной Альфы и массива полный единиц (которые оставят вас с массивом только единиц и нулей), умножьте это (по пикселям) на желаемую Альфу и скопируйте результат обратно в альфа-канал изображения (все еще представленный этой ссылкой на массив). Перед тем, как вы сможете стереть изображение на экран, ссылка массива на альфа-массив должна быть очищена, освобождая блокировку на поверхности изображения.
def change_alpha(img, alpha=255):
chan = pygame.surfarray.pixels_alpha(img)
chan2 = numpy.minimum(chan, numpy.ones(chan.shape, dtype=chan.dtype)) * alpha
numpy.copyto(chan, chan2)
del chan
Ok у меня есть ответ для вас. Функция "convert_alpha()" Pygame не поддерживает каждый пиксель Альфа. На основе настроек документов alpha не будет иметь никакого эффекта. Однако, вы можете обойти это ограничение следующим образом. Если вы загружаете свое изображение с помощью " convert ()", а затем устанавливаете alpha, вы можете сделать свое изображение прозрачным. Тогда все, что вам нужно сделать, это использовать "set_colorkey(цвет фона)", чтобы устранить фоновое изображение. Будьте carful с colorkey, потому что любой цвет в изображении это установлено как colorkey станет прозрачным. Colorkey не заботится об Альфе на пиксель, поэтому вы можете изменить Альфа изображения и использовать colorkey одновременно.
вот код...
#Loading Image
image = pygame.image.load("test.png").convert()
#Setting Alpha
image.set_alpha(some desired alpha)
#Set colorkey To Eliminate Background Color
image.set_colorkey(some background color)
Я бросил эту тестовую картинку вместе для тестирования кода. Изображение имеет прозрачность по краям.
Я надеюсь, что это то, что вы ищете, и надеялся, что мой ответ помог здесь.
Примечание* Вы можете сделать копию изображения, прежде чем изменить его альфа, как это без риска изображения, имеющего" перелив " влияет от предыдущих применений.
используйте set_colorkey (color) для установки прозрачного цвета. например, если у вас есть изображение яблока, и все, кроме яблока, имеет черный цвет, вы бы использовали apple.set_colorkey (черный), и все, кроме яблока, будет прозрачным. кроме того, если у вас возникли проблемы с использованием jpg-изображения, я бы предложил изменить его на png, а затем сделать .конвертировать.)(