Is it possible to fill pygame Surface with a color while keeping alpha layer intact without making another surface? [duplicate]

I have a set of surfaces that are all white with pixel alpha values, and I need to change their color as efficiently as possible (they will be blitted multiple tousand times each frame, example code is just scaled down). What I would need is to set all the pixel color values of each surface to one specific color while keeping the alpha layer the same. I know how to do that with making another surface and bliting them together, but that takes quite a lot of time (it more that halves the FPS in original code). Is there a way to color the surface without creating a new surface just for color ?

CAREFULL RUNNING IF YOU ARE PHOTOSENSITIVE (PROGRAM FLASHES COLORS FAST)

import pygame
import random

pygame.init()

WIDTH, HEIGHT = 500, 500
screen = pygame.display.set_mode((WIDTH, HEIGHT))
BLACK = (0, 0, 0)

characters = [chr(i) for i in range(32, 127)]
font = pygame.font.SysFont("consola", 25)
rendered_characters = [
    font.render(character, True, (255, 255, 255)).convert_alpha() for character in characters
]
clock = pygame.time.Clock()
ticks = 0
running = True
while running:
    screen.fill(BLACK)
    for i in pygame.event.get():
        if i.type == pygame.QUIT:
            running = False
            pygame.quit()
    clock.tick()
    ticks += 1
    if ticks % 60 == 0:
        print(clock.get_fps())
        ticks = 0
    
    for i, character in enumerate(rendered_characters):
        random_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))

        # This doesnt work
        #colored_character = character
        #colored_character.fill(random_color)
        
        # This works, but is quite slow
        colored_character = pygame.Surface(character.get_size()).convert_alpha()
        colored_character.fill(random_color)
        colored_character.blit(character, (0, 0), special_flags=pygame.BLEND_RGBA_MULT)
        
        screen.blit(colored_character, (i * 30 % (WIDTH - 30), 50 * (i * 30 // (WIDTH - 30))))
        
    pygame.display.update()

  • “Is there a way to color the surface without creating a new surface just for color?” – No, unfortunately not if you want to stay with Pygame and not use NumPy and OpenCV. Note that your question is a duplicate, as this question has already been asked. If there is a solution other than the one in the answers to the duplicates, this should be added in an alternative answer to one of these questions.

    – 




Leave a Comment