PyGame: Applying transparency to an image with alpha?

半腔热情 提交于 2019-11-29 15:14:13

问题


I want to display an image with alpha with a specified transparency, but can't figure out how to do it.

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.

#!/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?


回答1:


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.




回答2:


If you are just looking to load an image in pygame so it has an alpha channel, this is how to do so:

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

When you draw this image on the screen, it should include the transparency.




回答3:


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:

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

However, it does work after using Gimp to change 2 things:

  1. Image -> Mode -> Convert to Color Profile... and use the defaults
  2. 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...




回答4:


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.

It is all documented at http://www.pygame.org/docs/ref/surface.htm - but indeed, short in words or examples.

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.

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:

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!

You have to: create another surface, with the same size of your image, with depth = 24 Fill that surface with a color not in 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

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


来源:https://stackoverflow.com/questions/12879225/pygame-applying-transparency-to-an-image-with-alpha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!