PyGame:每像素alpha的半透明精灵

时间:2010-11-25 12:05:14

标签: python pygame transparent

是否可以显示具有可控alpha的PyGame表面?我想采用具有自己的每像素alpha的表面,并以不同的半透明度显示它而不影响表面数据并保持透明度完整,即表面上的物体将保持其形状但其“内容”变得或多或少半透明的。

换句话说,我希望将源图像中的每像素alpha与运行时计算的每表面alpha进行组合。

4 个答案:

答案 0 :(得分:7)

Pygame documentation表示您无法将表面alpha与每像素alpha结合使用,但如果您使用的是Pygame 1.8.1或更高版本,则可以使用special_flags解决此问题。参数.blit()

我是这样做的:

# Load an image with per-pixel alpha
s = pygame.image.load('spam.png')
s.convert_alpha()

# Simulate s.set_alpha(alpha)
alpha_img = pygame.Surface(s.get_rect().size, pygame.SRCALPHA)
alpha_img.fill((255, 255, 255, alpha))
s.blit(alpha_img, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)

这种方法的工作方式是创建与第一个相同大小的第二个表面,然后使用RGBA multiplication将其加到第一个表面上。通过使第二个图像的R,G和B分量等于255,乘法不会影响图像的颜色,但它会按给定的α因子缩放alpha通道。

请注意,上述方法与调用set_alpha()的不同之处在于set_alpha()可以通过调用set_alpha(255)来撤销void setup() { Serial.begin(9600); } void loop() { String message = ""; while (Serial.available()) message.concat((char) Serial.read()); if (message != "") Serial.println(message); } 。如果你使用上面的方法,它将导致每个像素的像素alpha被改变,所以这个过程不能直接逆转。

答案 1 :(得分:4)

是的,你可以。 documentation of the Surface class解释了如何做到这一点。它归结为两种情况: 您可以在创建Surface对象期间设置标志:

s = pygame.Surface((16, 16), flags=pygame.SRCALPHA)

或者您将Alpha通道提供给尚未拥有的表面:

s = pygame.image.load('spam.png')
s.convert_alpha()

pygame.image模块的文档说明对于具有透明度的PNG来说,应用convert_alpha是必要的。

如果您需要,可以使用模块draw和surfarray修改每个像素的alpha值。指定颜色时,请使用四个整数的元组:(红色,绿色,蓝色,alpha)。 alpha参数的范围从0(完全透明)到255(完全不透明)。

import pygame
pygame.init()
screen = pygame.display.set_mode((320, 200))
screen.fill((200, 100, 200))
s = pygame.Surface((64, 64), flags=pygame.SRCALPHA)
for i in range(64):
    pygame.draw.line(s, (0, 0, 0, i*4), (0, i), (64, i))

screen.blit(s, (50, 30))
pygame.display.flip()

答案 2 :(得分:4)

在检查了PyGame和SDL文档之后,我得出结论,我在PyGame中使用标准函数所提出的问题是不可行的。

SDL文档指出,每像素alpha和per-surface alpha不能与前者一起优先使用。实现我想要的效果的唯一方法是编写一个代码,在blit之前更新源表面的每像素alpha值。

答案 3 :(得分:1)

如果您的输入图像启用了每像素alpha,但只使用一位透明度(例如,带有透明背景或文本的.png精灵),则可以将透明背景转换为colorkey-alpha背景很容易,然后使用set_alpha()将整个纹理混合到任何地方。

这是一个快速而肮脏的辅助函数,我用它来淡化文本效果和其他东西:

def convert_to_colorkey_alpha(surf, colorkey=pygame.color.Color("magenta")):
    newsurf = surface.Surface(surf.get_size())
    newsurf.fill(colorkey)
    newsurf.blit(surf, (0, 0))
    newsurf.set_colorkey(colorkey)
    return newsurf

可能解决此问题的其他一些技巧可能是:

  • 执行逐像素编辑以在blitting之前修改Alpha通道
  • 使用special_flags = BLEND_RGBA_MULT或BLEND_RGBA_SUB将白色或黑色填充的半透明表面涂抹到源表面。