[英]How do I change the colour of an image in Pygame without changing its transparency?
It sounds like a simple thing to do , but I'm struggling. 听起来很简单,但是我很挣扎。 I have a png image of a rectangle with a transparent centre called "zero".
我有一个透明中心为“零”的矩形的png图像。 I want to change the colour of the visible part of the image.
我想更改图像可见部分的颜色。 To try and change it, I have tried using "zero.fill" but no option I try changes only the non-transparent part, or it merges the new colour with the old and stays like that.
要尝试更改它,我尝试使用“ zero.fill”,但没有选择,我尝试仅更改非透明部分,或者将新颜色与旧颜色合并并保持原样。 I'm not keen on installing numpy as I wish to take the finished program to a friend who doesn't have it.
我不希望安装numpy,因为我希望将完成的程序带给没有该程序的朋友。 Any simple suggestions welcome.
任何简单的建议都欢迎。
I've got an example that works with per pixel alpha surfaces that can also be translucent. 我有一个示例,该示例适用于也可以是半透明的每个像素的alpha曲面。 The
fill
function just loops over the surface's pixels and sets them to the new color, but keeps their alpha value. fill
功能仅循环遍历曲面的像素并将其设置为新颜色,但保留其alpha值。 It's probably not recommendable to do this every frame with many surfaces. 建议不要在具有多个表面的每个帧中执行此操作。 (Press f, g, h to change the color.)
(按f,g,h更改颜色。)
import sys
import pygame as pg
def fill(surface, color):
"""Fill all pixels of the surface with color, preserve transparency."""
w, h = surface.get_size()
r, g, b, _ = color
for x in range(w):
for y in range(h):
a = surface.get_at((x, y))[3]
surface.set_at((x, y), pg.Color(r, g, b, a))
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
# Uncomment this for a non-translucent surface.
# surface = pg.Surface((100, 150), pg.SRCALPHA)
# pg.draw.circle(surface, pg.Color(40, 240, 120), (50, 50), 50)
surface = pg.image.load('bullet2.png').convert_alpha()
surface = pg.transform.rotozoom(surface, 0, 2)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_f:
fill(surface, pg.Color(240, 200, 40))
if event.key == pg.K_g:
fill(surface, pg.Color(250, 10, 40))
if event.key == pg.K_h:
fill(surface, pg.Color(40, 240, 120))
screen.fill(pg.Color('lightskyblue4'))
pg.draw.rect(screen, pg.Color(40, 50, 50), (210, 210, 50, 90))
screen.blit(surface, (200, 200))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
In this version, the visible and transparent parts are the other way round to the original question as per Ankur's suggestion. 在此版本中,根据Ankur的建议,可见部分和透明部分与原始问题相反。 Here is the essential working code:
这是基本的工作代码:
import pygame, sys
from pygame.locals import *
pygame.init()
def load_image(name):
image = pygame.image.load(name).convert()
return image
def resize(obj, w, h):
global scale
return pygame.transform.scale(obj, (int(w * scale), int(h * scale)))
pink = (255, 0, 160)
red = (255, 0, 0)
peach = (255, 118, 95)
blue = (0, 0, 255)
blue_1 = (38, 0, 160)
dark_yellow = (255, 174, 0)
green = (38, 137, 0)
orange = (255, 81, 0)
colour = [pink, red, peach, blue, blue_1, dark_yellow, green, orange, green]
clock = pygame.time.Clock()
scale = 4
screen = pygame.display.set_mode((292 * scale, 240 * scale),0, 32)
banner = load_image("banner.png") #292x35
zero = load_image("zero.png") #5x7
c = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
rgb = colour[c]
c = c + 1
if c > 7:
c = 0
pygame.draw.line(banner, rgb, (53, 21), (53, 27), 5) #line the same size as zero image
banner.blit(zero, (51, 21)) #blit image with transparency over line
large_banner = resize(banner, 292, 35)
screen.blit(large_banner, (0, 0))
clock.tick(120)
pygame.display.flip()
pygame.quit()
sys.exit()
This code for drop all color brightness 此代码用于降低所有颜色的亮度
def drop(surface):
w, h = surface.get_size()
for x in range(w):
for y in range(h):
r = surface.get_at((x, y))[0]
if r>150:
r-=50
g = surface.get_at((x, y))[1]
if g>150:
g-=50
b = surface.get_at((x, y))[2]
if b>150:
b-=50
a = surface.get_at((x, y))[3]
surface.set_at((x, y), pygame.Color(r, g, b, a))
img = pygame.image.load("image.png").convert_alpha()
drop(img)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.