python - 如何使用 alpha 通道为 png 图像着色?
问题描述
我正在尝试编写典型的 dvd 弹跳屏幕保护程序。我对它很满意,但我想在每次它撞到墙上时改变标志的颜色。我使用了 fill(),但徽标变为彩色矩形。我想改变标志的颜色,尊重图像的 alpha 通道。
from pygame import *
import random
#set canvas size variables
width = 700
height = 450
#draw canvas
screen = display.set_mode((width,height))
display.set_caption('Graphics')
#initial XY coordinates where game starts
x = random.randint(1, width)
y = random.randint(1, height)
#import logo
logo_img = image.load('dvd_logo_alpha.png')
R = 255
G = 255
B = 255
def logo(x,y):
screen.blit(logo_img, (x,y))
def Col():
R = random.randint(100,255)
G = random.randint(100,255)
B = random.randint(100,255)
#speed of the logo
dx = 3
dy = 3
endProgram = False
while not endProgram:
for e in event.get():
if e.type == QUIT:
endProgram = True
#speed changes position XY
x += dx
y += dy
#detection of collision with border of screen
if y<0 or y>height-47:
dy *= -1
R = random.randint(100,255)
G = random.randint(100,255)
B = random.randint(100,255)
if x<0 or x>width-100:
dx *= -1
R = random.randint(100,255)
G = random.randint(100,255)
B = random.randint(100,255)
screen.fill((0))
logo_img.fill((R,G,B)) #here is the problem I can not solve
logo(x,y)
display.update()
解决方案
首先,您必须创建一个带有 alpha 通道的图像,以使 png 图像的透明区域不可见。使用pygame.Surface.convert_alpha()创建一个带有 alpha 通道的表面:
tintImage = image.convert_alpha()
要为图像着色 pygame.Surface.fill()
,special_flags
也必须设置为BLEND_RGBA_MULT
。这导致图像的所有像素都与颜色相乘,而不是由颜色设置:
tintImage.fill((R, G, B, 255), None, BLEND_RGBA_MULT)
请注意,由于图像必须使用不同的颜色进行着色,因此必须保留原始图像。使用该函数logo
复制图像,并“着色”和“blit”图像的副本:
def logo(x, y, color):
tintImage = logo_img.convert_alpha()
tintImage.fill((R, G, B, 255), None, BLEND_RGBA_MULT)
screen.blit(tintImage, (x, y))
在程序的主循环中调用函数:
endProgram = False
while not endProgram:
for e in event.get():
if e.type == QUIT:
endProgram = True
#speed changes position XY
x += dx
y += dy
#detection of collision with border of screen
if y<0 or y>height-47:
dy *= -1
R = random.randint(100,255)
G = random.randint(100,255)
B = random.randint(100,255)
if x<0 or x>width-100:
dx *= -1
R = random.randint(100,255)
G = random.randint(100,255)
B = random.randint(100,255)
screen.fill((0))
#logo_img.fill((R,G,B)) #here is the problem I can not solve
logo(x, y, (R, G, B))
display.update()