【问题标题】:PyGame: Applying transparency to an image with alpha?PyGame:将透明度应用于具有 alpha 的图像?
【发布时间】:2012-10-14 04:10:44
【问题描述】:

我想以指定的透明度显示an image with alpha,但不知道该怎么做。

为了详细说明我是如何解决这个问题的,下面的简介是来自this SO answer 的一段稍微修改过的代码,但是如果你运行它,你会看到“图像”失去了它的原生 alpha,而“image2”的 alpha 永远不会改变!呸。

#!/usr/bin/env python

import pygame, sys

pygame.init()

window = pygame.display.set_mode((200, 200))
background = pygame.Surface((window.get_size()))
background.fill((255, 255, 255))
image = image2 = pygame.image.load('alpha.png')

image = image.convert()
rect = image.get_rect()

image2 = image2.convert_alpha()
rect2 = image2.get_rect()

rect2.left = rect.width + 1

i = 0
while True:
  for event in pygame.event.get():
    if event.type == 12:
      pygame.quit()
      sys.exit()

  image.set_alpha(i)
  image2.set_alpha(i)

  window.fill((255, 255, 255))
  window.blit(background, background.get_rect())
  window.blit(image, rect)
  window.blit(image2, rect2)

  if i == 255:
    i = 0
  else:
    i += 1

  pygame.display.update()
  pygame.time.Clock().tick(60)

那么……它是怎么做到的?

【问题讨论】:

  • 我不知道,但image = image2 = pygame.image.load('alpha.png') 可能引用了同一个实例,删除了图像 2 的透明度。
  • 您是在寻找每个像素的 alpha,还是每个表面一个 alpha 值?
  • 如果我分别声明 image 和 image2 ,我会得到相同的结果。老实说,我并不关心我是怎么做的,只要它是有效的并且我得到了想要的结果:改变图像或表面的透明度,同时保留原始的 alpha 值。

标签: python pygame alpha geometry-surface blit


【解决方案1】:

复制您要显示的图像(不要更改原始图像)并使用以下内容:

self.image = self.original_image.copy()
# this works on images with per pixel alpha too
alpha = 128
self.image.fill((255, 255, 255, alpha), None, pygame.BLEND_RGBA_MULT)

抱歉,没有提供完整的示例。

【讨论】:

  • 我发现如果你先通过convert_alpha 推送它们,这仅适用于 8 位调色图像。这很好;只需事先转换图像。 :D
【解决方案2】:

对于它的价值,我看到了不同的结果,具体取决于图像本身。在我的情况下,我发现使用 Gimp 更改图像可以让我保持代码简单:

image = pygame.image.load('path/to/my.png').convert()
image.set_alpha(128)
surface.blit(image, (0, 0))

使用该代码,以下精灵无法正常工作: http://www.spriters-resource.com/resources/sheets/47/50365.png

但是,在使用 Gimp 更改 2 件事后它确实有效:

  1. 图像 -> 模式 -> 转换为颜色配置文件...并使用默认值
  2. 图像 -> 模式 -> 索引...并使用默认值

保存更改后,它在 Ubuntu 中适用于我。我是新用户,无法发布结果图片...

【讨论】:

  • 在 Gimp 2.1 中,我没有找到第一个选项 (Image -> Mode -> Convert to Color Profile),但只执行第 2 步对我有用。
【解决方案3】:

如果您只是想在 pygame 中加载图像以使其具有 alpha 通道,请执行以下操作:

self.image = pygame.image.load("image file path").convert_alpha()

当您在屏幕上绘制此图像时,它应该包括透明度。

【讨论】:

  • 不是答案。他已经知道如何做到这一点,但想知道在使用具有像素 alpha 值的图像时如何更改图像宽 alpha。
  • 我知道这是一个旧线程,但是如果使用这种方法时它不包括透明度怎么办?
【解决方案4】:

您的代码有点复杂 :-) 但尽管如此,“非每像素” - 或 表面的“全局 alpha”很难在 Pygame 中正确完成。

所有内容都记录在http://www.pygame.org/docs/ref/surface.htm - 但实际上,文字或示例都很短。

发生的情况是,如果您正在使用 blitting 的表面(源)具有像素本身的 alpha 像素值(即 32 位深度),则由表面的 set_alpha 方法设置的“全局 alpha”值将被忽略。

要使用此“全局”alpha,您的源表面不得具有每像素 alpha。如果您的原始图像(在您的情况下为“alpha.png”文件)本身不使用透明度,这很容易实现 - 只需:

import pygame
pygame.init()
window = pygame.display.set_mode((200, 200))
image = pygame.image.load('alpha.png').convert(24)
image.set_alpha(128)
window.fill((255,255,255))
window.blit(image, (0,0))
pygame.display.flip()

但是,如果您的“alpha.png”本身确实使用了透明度,并且您打算保留它,那就更棘手了!

您必须:创建另一个表面,与您的图像尺寸相同,深度 = 24 用图像中使用的颜色not填充该表面(如“色度键”) - 在视频效果中,通常他们使用纯绿色或纯白色,但你 可以选择任何 RGB 值 - 如果您的图像是照片而不是像素艺术, 您将无法知道女巫价值不会被使用。随便挑一个,希望 不要有太多的“失败像素”。 所以,用这个主色填充你的表面,并将其设置为表面的主色: 该 colro 将在 blitting 时呈现完全透明。 然后,只需在这个中间表面上对原始图像进行 blit,在其上设置全局 alpha (set_alpha) 并将 blitit 到目标表面

在代码中,大致翻译为:

import pygame
pygame.init()
window = pygame.display.set_mode((200, 200))
image = pygame.image.load('alpha.png')
surface = pygame.Surface(image.get_size(), depth=24)
key = (0,255,0)
surface.fill(surface.get_rect(), key)
surface.set_colorkey(key)
surface.blit(image, (0,0))
surface.set_alpha(128) 
window.fill((255,255,255))
window.blit(surface, (0,0))
pygame.display.flip()

【讨论】:

  • 其实粉色/紫色是作为key的颜色
  • 由于前面提到的 alpha 技术遵循一种颜色,这是否意味着我不能像原始 PNG 那样拥有不同的 alpha?这会使诸如抗锯齿边缘和文本的边缘变脏,你知道吗?
  • 是的,就是这个意思。好处是,由于您无论如何都在淡化对象,因此锯齿伪影不太可能那么明显。
  • 如果颜色键接近目标表面(屏幕)上的背景颜色,则可以进一步减轻锯齿
  • 好消息:在 Pygame 2.0 中,引用文档,“每表面 alpha 可以与每像素 alpha 结合。” :-)
猜你喜欢
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
相关资源
最近更新 更多