Need to blit transparency on a surface in Pygame
You can create a surface with an alpha channel (pass the pygame.SRCALPHA
flag), fill it with an opaque color and then draw a shape with a transparent color onto it (alpha value 0).
import pygame as pg
pg.init()
screen = pg.display.set_mode((800, 600))
clock = pg.time.Clock()
BLUE = pg.Color('dodgerblue4')
# I just create the background surface in the following lines.
background = pg.Surface(screen.get_size())
background.fill((90, 120, 140))
for y in range(0, 600, 20):
for x in range(0, 800, 20):
pg.draw.rect(background, BLUE, (x, y, 20, 20), 1)
# This dark gray surface will be blitted above the background surface.
surface = pg.Surface(screen.get_size(), pg.SRCALPHA)
surface.fill(pg.Color('gray11'))
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEMOTION:
surface.fill(pg.Color('gray11')) # Clear the gray surface ...
# ... and draw a transparent circle onto it to create a hole.
pg.draw.circle(surface, (255, 255, 255, 0), event.pos, 90)
screen.blit(background, (0, 0))
screen.blit(surface, (0, 0))
pg.display.flip()
clock.tick(30)
pg.quit()
You can also achieve this effect with another surface instead of pygame.draw.circle
. For example you could create a white image with some transparent parts in your graphics editor and pass BLEND_RGBA_MIN
as the special_flags argument to Surface.blit
when you blit it onto the gray surface.
brush = pg.image.load('brush.png').convert_alpha()
# Then in the while or event loop.
surface.fill(pg.Color('gray11'))
surface.blit(brush, event.pos, special_flags=pg.BLEND_RGBA_MIN)
Pygame image transparency confusion
If you copy a transparent Surface to another Surface the target Surface has to provide transparency respectively per pixel alpha.
You can enable additional functions when creating a new surface. Set the SRCALPHA
flag to create a surface with an image format that includes a per-pixel alpha. The initial value of the pixels is (0, 0, 0, 0):
my_surface = pygame.Surface((width, height), pygame.SRCALPHA)
Use the following image
and adapt the method image_at
of the class SpriteSheet
. Use pygame.SRCALPHA
:
class SpriteSheet:
# [...]
def image_at(self, rectangle, colorkey = None):
"""Load a specific image from a specific rectangle."""
# Loads image from x, y, x+offset, y+offset.
rect = pygame.Rect(rectangle)
image = pygame.Surface(rect.size, pygame.SRCALPHA) # <----
image.blit(self.sheet, (0, 0), rect)
if colorkey is not None:
if colorkey == -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, pygame.RLEACCEL)
return image
Or use convert_alpha()
:
class SpriteSheet:
# [...]
def image_at(self, rectangle, colorkey = None):
"""Load a specific image from a specific rectangle."""
# Loads image from x, y, x+offset, y+offset.
rect = pygame.Rect(rectangle)
image = pygame.Surface(rect.size).convert_alpha() # <----
image.fill((0, 0, 0, 0)) # <---
image.blit(self.sheet, (0, 0), rect)
if colorkey is not None:
if colorkey == -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, pygame.RLEACCEL)
return image
See also:
- How can I make an Image with a transparent Backround in Pygame?
- How do I blit a PNG with some transparency onto a surface in Pygame?
Note that chess pieces can also be drawn through a Unicode text.
See Displaying unicode symbols using pygame
png images with transparent background don't work in pygame 2.0.0
PNGs have per pixel alpha. It is not necessary to set a color key. Simply blit
the protector on the tank. convert()
changes the pixel format to a format without alpha per pixel and removes the transparency information. Use convert_alpha()
instead:
class Player(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__(player_group, all_sprites)
slef.image = pygame.image.load('baloon.png').convert_alpha()
self.image = pygame.transform.scale(slef.image, (42, 94))
I suggest to modify the load_image
function:
def load_image(name, per_pixel_alpha = False, color_key = None):
fullname = os.path.join('textures', name)
try:
image = pygame.image.load(fullname)
except pygame.error as message:
print('Cannot load image:', name)
raise SystemExit(message)
if per_pixel_alpha:
image = image.convert_alpha()
else:
image = image.convert()
if color_key is not None:
if color_key == -1:
color_key = image.get_at((0, 0))
image.set_colorkey(color_key)
return image
class Player(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y):
super().__init__(player_group, all_sprites)
self.image = pygame.transform.scale(load_image('baloon.png', True), (42, 94))
self.rect = self.image.get_rect().move(pos_x, pos_y)
def update(self, *args):
pass
Transparent Image in Pygame
First, your image/surface needs to use per-pixel alpha, therefore call the convert_alpha()
method when you load it. If you want to create a new surface (as in the example), you can also pass pygame.SRCALPHA
to pygame.Surface
.
The second step is to create another surface (called alpha_surface
here) which you fill with white and the desired alpha value (the fourth element of the color tuple).
Finally, you have to blit the alpha_surface
onto your image and pass pygame.BLEND_RGBA_MULT
as the special_flags
argument. That will make
the opaque parts of the image translucent.
import pygame as pg
pg.init()
screen = pg.display.set_mode((800, 600))
clock = pg.time.Clock()
BLUE = pg.Color('dodgerblue2')
BLACK = pg.Color('black')
# Load your image and use the convert_alpha method to use
# per-pixel alpha.
# IMAGE = pygame.image.load('circle.png').convert_alpha()
# A surface with per-pixel alpha for demonstration purposes.
IMAGE = pg.Surface((300, 300), pg.SRCALPHA)
pg.draw.circle(IMAGE, BLACK, (150, 150), 150)
pg.draw.circle(IMAGE, BLUE, (150, 150), 130)
alpha_surface = pg.Surface(IMAGE.get_size(), pg.SRCALPHA)
# Fill the surface with white and use the desired alpha value
# here (the fourth element).
alpha_surface.fill((255, 255, 255, 90))
# Now blit the transparent surface onto your image and pass
# BLEND_RGBA_MULT as the special_flags argument.
IMAGE.blit(alpha_surface, (0, 0), special_flags=pg.BLEND_RGBA_MULT)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((50, 50, 50))
pg.draw.rect(screen, (250, 120, 0), (100, 300, 200, 100))
screen.blit(IMAGE, (150, 150))
pg.display.flip()
clock.tick(60)
pg.quit()
Using image transaprency make appear black things
convert_alpha()
does not convert the format of the surface itself, but creates a new surface with a format that provides a per pixel alpha format.
either
surface = pygame.Surface((tileSize, tileSize))
surface = surface.convert_alpha()
or
surface = pygame.Surface((tileSize, tileSize)).convert_alpha()
There are 3 ways to create a transparent Surface:
Set a transparent color key with
set_colorkey()
The color key specifies the color that is treated as transparent. For example, if you have an image with a black background that should be transparent, set a black color key:
surface.set_colorkey((0, 0, 0))
You can enable additional functions when creating a new surface. Set the
SRCALPHA
flag to create a surface with an image format that includes a per-pixel alpha. The initial value of the pixels is (0, 0, 0, 0):surface = pygame.Surface((tileSize, tileSize), pygame.SRCALPHA)
Use
convert_alpha()
to create a copy of the Surface with an image format that provides alpha per pixel.However, if you create a new surface and use
convert_alpha()
, the alpha channels are initially set to maximum. The initial value of the pixels is (0, 0, 0, 255). You need to fill the entire surface with a transparent color before you can draw anything on it:surface = pygame.Surface((tileSize, tileSize))
surface = surface.convert_alpha()
surface.fill((0, 0, 0, 0))
Related Topics
Hexadecimal String to Byte Array in Python
Circular Import Dependency in Python
What Does the 'U' Symbol Mean in Front of String Values
Using Os.Walk() to Recursively Traverse Directories in Python
Method Resolution Order (Mro) in New-Style Classes
Understanding Nested List Comprehension
Access a Function Variable Outside the Function Without Using "Global"
How to Correctly Clean Up a Python Object
How to Turn a Python Datetime into a String, with Readable Format Date
How to Convert a String of Bytes into an Int
Create Nice Column Output in Python
Importerror: No Module Named 'Tkinter'
Non-Alphanumeric List Order from Os.Listdir()
Unicodedecodeerror: 'Utf8' Codec Can't Decode Byte 0Xa5 in Position 0: Invalid Start Byte
Python Nameerror: Name Is Not Defined
Pandas Long to Wide Reshape, by Two Variables
Determine Function Name from Within That Function (Without Using Traceback)