0

I'm using pygame for image editing (not displaying). (Yes, I know there are other options like PIL/pillow, but pygame should work for this.)

I want to draw and save an image where I'm individually setting the alpha values of each pixel according to a formula (I'm drawing a complicated RGBA profile). It seems that pixels_alpha is the right way to do this. But when I change pixels_alpha it's ignored, the image just stays transparent. Here's my code...

import pygame as pg
import os
def init_transparent(img_width, img_height):
    """
    Create a new surface with width and height, starting with transparent
    background. This part works!
    """
    os.environ['SDL_VIDEODRIVER'] = 'dummy'
    pg.init()
    pg.display.init()
    # next command enables alpha
    # see http://stackoverflow.com/questions/14948711/
    pg.display.set_mode((img_width, img_height), 0, 32)
    # pg.SRCALPHA is a flag that turns on per-pixel alpha.
    return pg.Surface((img_width, img_height), pg.SRCALPHA)

def make_semitransparent_image():
    surf = init_transparent(20, 20)
    # alphas should be a direct reference to the alpha data in surf
    alphas = pg.surfarray.pixels_alpha(surf)
    # alphas is a uint8-dtype numpy array. Right now it's all zeros.
    for i in range(20):
        for j in range(20):
            # Since pixels_alpha gave me a uint8 array, I infer that
            # alpha=255 means opaque. (Right?)
            alphas[i,j] = 200
    pg.image.save(surf, '/home/steve/Desktop/test.png')

make_semitransparent_image()

Again, it saves an image but the image looks completely transparent, no matter what value I set alphas to. What am I doing wrong here? (Using Python 2.7, pygame 1.9.1release.) (Thanks in advance!)

4

1 回答 1

1

The Pygame docs say that pixels_array() locks the surface as long as the resulting array exists, and that locked surface may not be drawn correctly. It seems to be the case that they are not saved correctly, too. You need to throw away the alphas surfarray object before calling image.save(). This can be done by adding del alphas just before image.save().

(Note that this is more a workaround than a proper fix. Adding del alphas can only have a reliable effect only on CPython (and not PyPy, Jython, IronPython). Maybe you can really "close" a surfarray objects, the same way you can either close a file or merely forget about it?)

于 2013-07-07T15:40:43.127 回答