How do I blit a PNG with some transparency onto a surface in Pygame?
Asked Answered
S

4

23

I'm trying to blit a PNG image onto a surface, but the transparent part of the image turns black for some reason, here's the simple code:

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))

What do I have to do to solve the problem? The image has alpha transparency, I've opened it up in PhotoShop and the background turns transparent, not black or white or any other color.

Thank you for your support :)

Spaceman answered 27/10, 2009 at 23:9 Comment(0)
S
30

http://www.pygame.org/docs/ref/image.html recommends:

For alpha transparency, like in .png images use the convert_alpha() method after loading so that the image has per pixel transparency.

Skippie answered 28/10, 2009 at 0:57 Comment(2)
pygame.image.load will already have alpha when loaded from an image with alpha.Misjoinder
@PeterShinners actually, calling convert() or convert_alpha() is still preferred since not doing so will mean that blits will all require pixel format conversion, which is extremely slow.Allay
L
10

You did not flip the doublebuffer.

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()

This should work for your problem.

Liberate answered 11/12, 2012 at 7:57 Comment(0)
B
3

Images are represented by "pygame.Surface" objects. A Surface can be created from an image with pygame.image.load:

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

However, the pygame documentation notes that:

The returned Surface will contain the same color format, colorkey and alpha transparency as the file it came from. You will often want to call convert() with no arguments, to create a copy that will draw more quickly on the screen.
For alpha transparency, like in .png images, use the convert_alpha() method after loading so that the image has per pixel transparency.

Use the convert_alpha() method for best performance:

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

A Surface can be drawn on or blended with another Surface using the blit method. The first argument to blit is the Surface that should be drawn. The second argument is either a tuple (x, y) representing the upper left corner or a rectangle. With a rectangle, only the upper left corner of the rectangle is taken into account. It should be mentioned that the window respectively display is also represented by a Surface. Therefore, drawing a Surface in the window is the same as drawing a Surface on a Surface:

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

Minimal example: 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()
Bibliopole answered 1/11, 2020 at 10:8 Comment(0)
M
0

Your code looks like it should be correct. The SDL library does not support alpha to alpha blitting like this, but Pygame added support for it awhile ago. In Pygame 1.8 support was added for custom blending modes, and I wonder if that removed Pygame's internal alpha-to-alpha blitter?

Alas, further investigation will be required.

Misjoinder answered 6/11, 2009 at 18:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.