Gettin alpha channel data from an image in Pyglet quickly

301 Views Asked by At

I'm trying to get an array with the alpha channel value of a sprite image, using Pyglet library. I wrote this code which actually works:

mask = []
for x in range(image.width):
    mask.append([])
    for y in range(image.height):
        mask[x].append(ord(image.get_region(x, y, 1, 1).get_image_data().get_data("RGBA", 4)[3]))
return mask

The only problem is that it's really really slow, I guess I'm using a wrong function to retrieve the alpha channel. What can I do to make it faster?

UPDATE

I find a solution with the following code which is faster:

rawimage = image.get_image_data()
format = 'RGBA'
pitch = rawimage.width * len(format)
pixels = rawimage.get_data(format, pitch)

data = unpack("%iB" % (4 * image.width * image.height), pixels)
mask = data[3::4]
return mask
1

There are 1 best solutions below

1
On

I don't know pyglet, but I'm guessing the performance issue is related to the many queries for only a single pixel. Instead you want to get the entire image from the GPU in just one call, including the colour and alpha values, and then extract just the alpha. I'd also use struct.unpack instead of ord().

Note: This code is untested and purely based on the example in the question. There is probably a better way.

from struct import unpack
...
region = image.get_region(0, 0, image.width, image.height)
packed_data = region.get_image_data().get_data("RGBA", 4)
data = unpack("%iB" % (4 * image.width * image.height), packed_data)
mask = data[3::4]

I don't think it'd be worth it but if you really didn't want to drag colour back from the GPU you could explore copying alpha to another texture first (there might even be a way to get GL to unpack it as a format conversion or reinterpretation).