Is it possible to display PyGame surfaces with controllable alpha? I would like to take a surface with its own per pixel alpha and display it with variable level of translucency without affecting the surface data and keep the transparency intact i.e. the objects on the surface would keep their shapes but their "contents" becoming more or less translucent.
In other words I want to combine per-pixel alpha from the source image with per-surface alpha calculated at the runtime.
Surface. convert_alpha: It creates a new copy of the surface with the desired pixel format. The new surface will be in a format suited for quick blitting to the given format with per-pixel alpha. If no surface is given, the new surface will be optimized for blitting to the current display.
There are three types of transparency supported in pygame: colorkeys, surface alphas, and pixel alphas. Surface alphas can be mixed with colorkeys, but an image with per pixel alphas cannot use the other modes. Colorkey transparency makes a single color value transparent.
The Pygame documentation says that you can't combine surface alpha with per-pixel alpha, but if you're using Pygame 1.8.1 or newer, you can work around this by using the special_flags
parameter to .blit()
.
Here's how I did it:
# Load an image with per-pixel alpha
s = pygame.image.load('spam.png')
s = 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)
The way this works is to create a second surface the same size as the first, and blit it on to the first using RGBA multiplication. By having the R, G and B components of the second image equal to 255, the multiplication won't affect the colour of the image, but it will scale the alpha channel by the given alpha factor.
Note that the method above differs from calling set_alpha()
in that set_alpha()
can be reversed by calling set_alpha(255)
. If you use the method above it will result in the pixel alphas of every pixel being changed, so the process cannot be straightforwardly reversed.
If your input image has per-pixel alpha enabled, but is only using a single bit for transparency (e.g., .png sprites with a transparent background or text), you can convert the transparent background to a colorkey-alpha background pretty easily, and then use set_alpha() to blend the whole texture onto whatever.
This is a quick and dirty helper function I used for fading text effects and other things:
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
A couple of other tricks potentially solve this problem might be:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With