简体   繁体   English

如何在Pygame中更改图像的颜色而不更改其透明度?

[英]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()

bullet2.png

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.

相关问题 如何在pygame中更改弹丸的位置而不改变其面对每个循环? - How can I change the location of a projectile in pygame without changing its facing every loop? 如何检测鼠标是否悬停在按钮上? PyGame 按钮类在悬停时不显示文本或更改颜色 - How do I detect if the mouse is hovering over a button? PyGame button class is not displaying the text or changing colour on hover 如何相对于其中心缩放 PyGame 图像(表面)? - How do I scale a PyGame image (Surface) with respect to its center? 如何使用 Pygame 围绕其中心旋转图像? - How do I rotate an image around its center using Pygame? 如何在OpenCV中更改图像的透明度? - How do you change the transparency of an image in OpenCV? Pygame 如何在不擦除其他任何内容的情况下更改背景颜色 - Pygame how to change background colour without erasing anything else 在 pygame 中单击时如何更改按钮的图像? - How do I change the image of a button when it's clicked in pygame? 如何获取pygame中鼠标单击位置的RGB值以及如何更改颜色? (Python 3.3.2) - How do I get the RGB value for where my mouse clicks in pygame and how do I change the colour? (Python 3.3.2) 如何在pygame中旋转表面而不改变其形状 - How to rotate a surface in pygame, without changing its shape pygame图像透明度不显示 - pygame image transparency not showing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM