Search code examples
pythonpygamepng

png images with transparent background don't work in pygame 2.0.0


When I load my png image with transparent background as a sprite image there are very weird background on it. I used Photoshop to draw the image.

Also, there are an error: libpng warning: iCCP: known incorrect sRGB profile

It appears only when I close the pygame window.

I attach my code, png image and screenshot of how does it works below.

import os
import pygame

FPS = 50
WIDTH, HEIGHT = 500, 500

pygame.init()

size = width, height = WIDTH, HEIGHT
screen = pygame.display.set_mode(size)

all_sprites = pygame.sprite.Group()
player_group = pygame.sprite.Group()


def load_image(name, color_key=None):
    fullname = os.path.join('textures', name)
    try:
        image = pygame.image.load(fullname).convert()
    except pygame.error as message:
        print('Cannot load image:', name)
        raise SystemExit(message)

    if color_key is not None:
        if color_key == -1:
            color_key = image.get_at((0, 0))
        image.set_colorkey(color_key)
    else:
        image = image.convert_alpha()
    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', 1), (42, 94))

        self.rect = self.image.get_rect().move(pos_x, pos_y)

    def update(self, *args):
        pass


clock = pygame.time.Clock()
player = Player(200, 200)
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill(pygame.Color("#AAAAAA"))
    all_sprites.draw(screen)

    all_sprites.update()
    pygame.display.flip()
    clock.tick(FPS)
pygame.quit()

baloon.png

this is how does it seen


Solution

  • 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