Search code examples
pythonpygametransparencypygame-surface

Pygame Surface.set_at is setting alpha to 255?


I have this code:

import pygame, sys

pygame.init()

screen = pygame.display.set_mode([640,480])
screen.fill([100,100,100])
pygame.display.flip()

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

surf = pygame.Surface([1024,1024])

for y in range(0,1024):
    for x in range(0,1024):
        surf.set_at((x,y), image.get_at((x,y)))
        if x == 0 and y == 0:
            print image.get_at((x,y))
            print surf.get_at((x,y))

running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill([100,100,100])

    screen.blit(surf, [0,0])

    pygame.display.flip()

pygame.quit()

what it does is it opens an image and then copies it to a different surface (surf) than the original (image). tree.png is transparent in parts, particularly at x:0,y:0. When I am copying, if x is 0 and y is 0 then I will print out the color value of the original image and the color value of the new surface. But the problem is that whenever I copy the surface over, the alpha is always changed to 255, making it a non-transparent image. I thought using convert_alpha would save the correct alpha values (and it did for the original image, not the new surface). Is there a fix for this?


Solution

  • The issue is not caused by the image Surface but by the surf Surface. The Surface created from the PNG file has a per pixel alpha format. However, you must create a target Surface with per pixel alpha format, by specifying the SRCALPHA flag:

    surf = pygame.Surface([1024,1024])

    surf = pygame.Surface([1024,1024], pygame.SRCALPHA)
    

    Alternatively you can change the pixel format of an Surface including per pixel alphas with convert_alpha:

    surf = pygame.Surface([1024,1024]).convert_alpha()