【问题标题】:How do I blit a PNG with some transparency onto a surface in Pygame?如何在 Pygame 中将具有一定透明度的 PNG 粘贴到表面上? [复制]
【发布时间】:2010-12-10 16:34:29
【问题描述】:

我正在尝试将 PNG 图像 blit 到表面上,但图像的透明部分由于某种原因变成黑色,这是简单的代码:

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

我必须做些什么来解决这个问题? 该图像具有 Alpha 透明度,我已在 PhotoShop 中打开它,背景变为透明,而不是黑色或白色或任何其他颜色。

感谢您的支持:)

【问题讨论】:

    标签: python png pygame alpha blit


    【解决方案1】:

    http://www.pygame.org/docs/ref/image.html推荐:

    对于 alpha 透明度,就像在 .png 图像中一样,在加载后使用 convert_alpha() 方法,以便图像具有每个像素的透明度。

    【讨论】:

    • pygame.image.load 从带有 alpha 的图像加载时已经具有 alpha。
    • @PeterShinners 实际上,调用convert()convert_alpha() 仍然是首选,因为不这样做意味着blits 都需要像素格式转换,这非常慢。
    【解决方案2】:

    你没有翻转双缓冲。

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

    这应该可以解决您的问题。

    【讨论】:

      【解决方案3】:

      图像由"pygame.Surface" 对象表示。 Surface 可以从带有pygame.image.load 的图像创建:

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

      但是,pygame 文档指出:

      返回的 Surface 将包含与其来源文件相同的颜色格式、颜色键和 alpha 透明度。您经常需要不带参数地调用convert(),以创建一个可以更快地在屏幕上绘制的副本。
      对于 alpha 透明度,就像在 .png 图像中一样,在加载后使用convert_alpha() 方法,以便图像具有每个像素的透明度。

      使用convert_alpha() 方法以获得最佳性能:

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

      Surface 可以使用blit 方法在另一个Surface 上绘制或混合。 blit 的第一个参数是应该绘制的 Surface。第二个参数是表示左上角的元组 (x, y) 或矩形。对于矩形,只考虑矩形的左上角。需要说明的是,窗口分别显示也是由一个Surface来表示的。因此,在窗口中绘制Surface与在Surface上绘制Surface是一样的:

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

      最小示例: 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()
      

      【讨论】:

        【解决方案4】:

        您的代码看起来应该是正确的。 SDL 库不支持像这样的 alpha 到 alpha blitting,但 Pygame 不久前增加了对它的支持。在 Pygame 1.8 中添加了对自定义混合模式的支持,我想知道这是否删除了 Pygame 的内部 alpha-to-alpha blitter?

        唉,还需要进一步调查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-09
          • 1970-01-01
          • 2019-05-18
          • 1970-01-01
          相关资源
          最近更新 更多