Python PyGame:使用 alpha 将透明度应用于图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12879225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PyGame: Applying transparency to an image with alpha?
提问by Synthead
I want to display an image with alphawith a specified transparency, but can't figure out how to do it.
我想显示具有指定透明度的alpha 图像,但不知道该怎么做。
To elaborate on how I'm struggling with this, the blurb below is a slightly modified hunk of code from this SO answer, but if you run it, you'll see that "image" loses it's native alpha, while the alpha of "image2" never changes! Yuck.
为了详细说明我是如何解决这个问题的,下面的简介是来自这个 SO answer 的一小段代码,但是如果你运行它,你会看到“图像”失去了它的原生 alpha,而“的 alpha” image2”永远不会改变!哎呀。
#!/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)
So ... how is it done?
那么......它是如何完成的?
回答by jsbueno
your code is a bit convoluted :-) but nonetheless, "non-per-pixel" - or "global alpha" for a surface is tricky to get done right in Pygame.
您的代码有点复杂:-) 但是,表面的“非每像素”或“全局 alpha”很难在 Pygame 中正确完成。
It is all documented at http://www.pygame.org/docs/ref/surface.htm- but indeed, short in words or examples.
这一切都记录在http://www.pygame.org/docs/ref/surface.htm- 但实际上,文字或示例都很简短。
What happens is that if the surface you are blitting (the source) has alpha pixels values for the pixels itself (i.e. 32 bit depth), a "global alpha" value,as set by the surface's set_alpha method will be ignored.
发生的情况是,如果您正在 blitting 的表面(源)具有像素本身的 alpha 像素值(即 32 位深度),则由表面的 set_alpha 方法设置的“全局 alpha”值将被忽略。
For this "global" alpha to be used, your source surface must not have per pixel alpha. That is easy to achieve if your original image (inyour case the "alpha.png" file) uses no transparency itself - just a matter of:
要使用此“全局”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()
However, if your "alpha.png" does use transparency itself, and you intend to preserve it, gets trickier!
但是,如果您的“alpha.png”确实使用了透明度本身,并且您打算保留它,则会变得更加棘手!
You have to: create another surface, with the same size of your image, with depth = 24 Fill that surface with a color notin use in your image (like "chroma key") - In video effects, normaly they use pure green or pure white for that, but you can choose any RGB value - if your image is a photo instead of pixel art, you won't be able to know witch value won't be in use. Just pick any, and hope not to have too much "failed pixels". So, fill your surface with this key color, and set it as the key color for the surface: that colro will render fully transparent when blitting. Then, just blit your original image on this intermediary surface, set the global alpha on it (set_alpha) and blitit to your destination surface
您必须: 创建另一个与图像大小相同的表面,深度 = 24用图像中未使用的颜色填充该表面(如“色度键”) - 在视频效果中,通常它们使用纯绿色或纯白色,但您可以选择任何 RGB 值 - 如果您的图像是照片而不是像素艺术,您将无法知道不会使用女巫值。随便选一个,希望不要有太多的“失败像素”。所以,用这个关键颜色填充你的表面,并将它设置为表面的关键颜色:在 blit 时,那个颜色将呈现完全透明。然后,只需在此中间表面上对原始图像进行 blit,在其上设置全局 alpha (set_alpha) 并 blitit 到您的目标表面
In code, it translates roughly to:
在代码中,它大致翻译为:
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()
回答by DR0ID
Make a copy of the image you want to show (to not change the original) and use following:
复制要显示的图像(不要更改原始图像)并使用以下内容:
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)
Sorry, to not provide a full example.
抱歉,没有提供完整的示例。
回答by trevorKirkby
If you are just looking to load an image in pygame so it has an alpha channel, this is how to do so:
如果您只是想在 pygame 中加载图像以使其具有 alpha 通道,请执行以下操作:
self.image = pygame.image.load("image file path").convert_alpha()
When you draw this image on the screen, it should include the transparency.
当您在屏幕上绘制此图像时,它应该包括透明度。
回答by moorecm
For what it's worth, I've seen varying results depending on the image itself. In my situation, I found that using Gimp to change the image allowed me to keep the code simple:
对于它的价值,我看到了不同的结果,具体取决于图像本身。在我的情况下,我发现使用 Gimp 更改图像可以使代码保持简单:
image = pygame.image.load('path/to/my.png').convert()
image.set_alpha(128)
surface.blit(image, (0, 0))
Using that code, the following sprites just don't work right: http://www.spriters-resource.com/resources/sheets/47/50365.png
使用该代码,以下精灵无法正常工作:http: //www.spriters-resource.com/resources/sheets/47/50365.png
However, it does work after using Gimp to change 2 things:
但是,它在使用 Gimp 更改两件事后确实有效:
- Image -> Mode -> Convert to Color Profile... and use the defaults
- Image -> Mode -> Indexed... and use the defaults
- 图像 -> 模式 -> 转换为颜色配置文件...并使用默认值
- 图像 -> 模式 -> 索引...并使用默认值
After saving the changes, it works for me in Ubuntu. I can't post an image of the result because I'm a new user...
保存更改后,它在 Ubuntu 中对我有用。我无法发布结果的图像,因为我是新用户...

