如何在不改变透明度的情况下更改Pygame中图像的颜色?

时间:2017-03-15 21:56:19

标签: python pygame

这听起来很简单,但我很挣扎。 我有一个带有透明中心的矩形的png图像,称为“零”。我想改变图像可见部分的颜色。要尝试更改它,我尝试使用“zero.fill”,但没有选项我尝试只更改非透明部分,或者它将新颜色与旧颜色合并并保持这样。 我并不热衷于安装numpy,因为我希望将完成的程序带给没有它的朋友。欢迎任何简单的建议。

3 个答案:

答案 0 :(得分:1)

我有一个适用于每像素alpha表面的例子,它也可以是半透明的。 fill函数只是在表面的像素上循环,并将它们设置为新颜色,但保留其alpha值。可能不建议每个具有许多表面的框架都这样做。 (按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()

bullet2.png

答案 1 :(得分:1)

在这个版本中,根据Ankur的建议,可见和透明的部分与原始问题相反。 这是基本的工作代码:

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()

答案 2 :(得分:0)

此代码用于降低所有颜色的亮度

    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)