如何在Pygame中将带透明度的PNG绘制到表面上?

23 投票
4 回答
30402 浏览
提问于 2025-04-15 15:26

我正在尝试把一张PNG图片放到一个表面上,但图片的透明部分不知道为什么变成了黑色。这是我写的简单代码:

screen = pygame.display.set_mode((800, 600), pygame.DOUBLEBUF, 32)

world = pygame.Surface((800, 600), pygame.SRCALPHA, 32)
treeImage = pygame.image.load("tree.png")

world.blit(treeImage, (0,0), (0,0,64,64))
screen.blit(world, pygame.rect.Rect(0,0, 800, 600))

我该怎么做才能解决这个问题呢?这张图片有透明度,我在Photoshop里打开时,背景是透明的,不是黑色、白色或其他颜色。

谢谢你的支持 :)

4 个回答

3

图片在这里是通过 "pygame.Surface" 对象来表示的。你可以用 pygame.image.load 从一个图片文件创建一个 Surface

my_image_surface = pygame.load.image('my_image.jpg')

不过,pygame 的文档提到:

返回的 Surface 会保留和原文件一样的颜色格式、颜色键和透明度。如果你想让图像在屏幕上显示得更快,通常需要调用 convert() 方法,不带任何参数,这样会创建一个更快的副本。
对于像 .png 这样的带透明度的图像,加载后要使用 convert_alpha() 方法,这样图像就会有每个像素的透明度。

为了获得最佳性能,使用 convert_alpha() 方法:

alpha_image_surface = pygame.load.image('my_icon.png').convert_alpha()

你可以用 blit 方法把一个 Surface 绘制到另一个 Surface 上。blit 方法的第一个参数是要绘制的 Surface,第二个参数可以是一个元组(x, y),表示左上角的位置,或者是一个矩形。如果用矩形的话,只考虑矩形的左上角。需要提到的是,窗口或显示屏也是一个 Surface。所以在窗口中绘制一个 Surface 就和在一个 Surface 上绘制一个 Surface 是一样的:

window_surface.blit(image_surface, (x, y))
window_surface.blit(image_surface,
    image_surface.get_rect(center = window_surface.get_rect().center))

最简单的例子: repl.it/@Rabbid76/PyGame-LoadTransparentImage

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

pygameSurface = pygame.image.load('Porthole.png').convert_alpha()

background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *window.get_size(), (160, 160, 160), (192, 192, 192)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect, color in tiles:
    pygame.draw.rect(background, color, rect)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    window.blit(background, (0, 0))
    window.blit(pygameSurface, pygameSurface.get_rect(center = window.get_rect().center))
    pygame.display.flip()

pygame.quit()
exit()
10

你没有切换双缓冲。

import pygame
from pygame.locals import Color

screen = pygame.display.set_mode((800, 600))

treeImage = pygame.image.load("tree.png").convert_alpha()

white = Color('white')

while(True):
    screen.fill(white)
    screen.blit(treeImage, pygame.rect.Rect(0,0, 128, 128))
    pygame.display.flip()

这样做应该能解决你的问题。

30

在这里,http://www.pygame.org/docs/ref/image.html 提到:

如果你想要使用像 .png 这种支持透明度的图片,记得在加载图片后使用 convert_alpha() 方法,这样图片的每个像素都可以有自己的透明度。

撰写回答