Skip to main content
 首页 » 编程设计

python之在 Pygame 中,如何 headless 地将透明图像保存到文件中

2025年05月04日13mengfanrong

这是我最近提出的一个问题:

In Pygame, how can I save a screen image in headless mode?

我能够保存涉及非透明表面对象的屏幕图像。但是,该技术不适用于透明表面对象。下面的代码说明了这个问题:

import sys 
import os 
import pygame 
from pygame.color import THECOLORS as RGB 
 
 
class PygameProblemDemo(object): 
     
    def __init__(self): 
        screen_width, screen_height = 200, 200 
        os.environ['SDL_VIDEODRIVER'] = 'dummy' 
         
        pygame.init() 
        pygame.display.init() 
         
        self.screen = pygame.display.set_mode((screen_width, screen_height)) 
     
    def save_non_alpha_image(self): 
        r = 50 
        color = RGB['blue'] 
        img_path = '/tmp/non_alpha_image.png' 
         
        background = pygame.Surface((200, 200), pygame.SRCALPHA, 32) 
        pygame.draw.rect(background, RGB['lightgray'], (0, 0, 200, 200), 0) 
         
        self.screen.fill(RGB['black']) 
        self.screen.blit(background, (0,0)) 
        pygame.draw.circle(self.screen, color, (100,100), r, 0) 
         
        pygame.image.save(self.screen, img_path) 
        print "image saved to %s" % (img_path) 
     
    def save_alpha_image(self): 
        r = 50 
        color = RGB['blue'] 
        img_path = '/tmp/alpha_image.png' 
         
        background = pygame.Surface((200, 200), pygame.SRCALPHA, 32) 
        pygame.draw.rect(background, RGB['lightgray'], (0, 0, 200, 200), 0) 
         
        transparent_circle = self.draw_transparent_circle(r, color, 50) 
         
        self.screen.fill(RGB['black']) 
        self.screen.blit(background, (0,0)) 
        self.screen.blit(transparent_circle, (50,50)) 
         
        pygame.image.save(self.screen, img_path) 
        print "image saved to %s" % (img_path) 
     
    def draw_transparent_circle(self, radius, color, transparency=0): 
        """transparency is value between 0 and 100, 0 is opaque, 
        100 invisible""" 
        width, height = radius*2, radius*2 
         
        # transparent base surface 
        flags = pygame.SRCALPHA 
        depth = 32 
        base = pygame.Surface((width, height), flags, depth) 
         
        # alpha surface 
        alpha = int(round(255 * (100-transparency) / 100.0)) 
        alpha_surface = pygame.Surface((width, height)) 
        alpha_surface.set_colorkey(RGB['black']) 
        alpha_surface.set_alpha(alpha) 
         
        # draw circle (to alpha surface) 
        pygame.draw.circle(alpha_surface, color, (radius,radius), radius) 
         
        # draw alpha surface to base surface 
        base.blit(alpha_surface, (0,0)) 
         
        return base 
     
     
demo = PygameProblemDemo() 
demo.save_non_alpha_image() 
demo.save_alpha_image() 

结果如下:

non_alpha_image.png

alpha_image.png


更新

如果我在构造函数中注释掉 os.environ['SDL_VIDEODRIVER'] = 'dummy' 行,透明图像将成功保存:

alpha_image.png

但是,那一行禁止窗口打开,所以脚本不能再 headless 运行。 :\

请您参考如下方法:

我想通了。 Pygame 显示需要在启用 alpha channel 的情况下启动。要修复上面的示例,只需替换构造函数中的这一行:

self.screen = pygame.display.set_mode((screen_width, screen_height)) 

有了这个:

self.screen = pygame.display.set_mode((screen_width, screen_height), 0, 32)