Open GalacticEmperor1 opened 1 year ago
Will surfarray.make_surface
support create alpha channel finally? Since this issue is still open and has an [enhancement]
tag.
@llindstrom Thanks you have rescued my project. I had been through the docs and could not see any way to set alpha values for a surface (except setting the values all to same integer). The only way I could find was saving an array with transparency values as a png using opencv and then reading that in as a surface.
I would like to see a method for blitting numpy arrays onto a surface. At the moment you can only do this if the array has same dimensions as surface and alpha values are not supported.
It would also be great to see a convenience method for converting from opencv numpy formats to pygame ones, but that should probably be a separate request.
@Haperth I think these are what you're looking for? pygame.image.tobytes pygame.image.frombytes
Or maybe the surfarray API?
@oddbookworm Thanks, I had missed those methods. In case anybody else needs this, an opencv format numpy image with transparency can be converted to a pygame surface as follows:
pygame.image.frombytes(array.tobytes(), (array.shape[1], array.shape[0]), 'BGRA')
Issue №1244 opened by robertpfeiffer at 2019-08-13 14:19:47
Reported by Discord user JoKing# 4832:
The shape of the numpy array is explicitly checked in pixelcopy.c; Either it can be a 2D array of 32bit ints (which are interpreted as RGB only, the byte corresponding to the alpha channel is ingored), or a 3D array where the first two dimensions are x any y, and the third is the different colours and has to be exactly size 3.
At the very least, we will need to change the error message to explain that not all 3D arrays are accepted, only those where the third dimension has size 3. This is a one-line fix.
But we could also create an alpha channel, at least when the input is a 3D array with size 4 in the 3rd dimension. In that case, the behaviour of 2D and 3D arrays would be inconsistent with each other, but backwards compatibility would be maintained. That would be more than a quick fix and require additional unit tests and probably a new, different code path.
Related Docs: https://www.pygame.org/docs/ref/surfarray.html
Comments
*MyreMylar commented at 2020-05-15 20:00:46*
Merging info from 1513:
*carlosgmartin commented at 2020-10-08 06:41:40*
@MyreMylar What's the right way to proceed when the array has an alpha channel? How can one create the corresponding surface?
*llindstrom commented at 2021-01-17 07:25:26*
Support for (w, h, 4) arrays was omitted from surfarray because 32 bit source alpha surfaces have differing alpha channel placement within a pixel. Depending on various factors such as hardware and operating system the channel order may be RGBA or ARGB, making indexing inconsistent for pixels3d arrays. However, other surfarray functions could be made to accept, or return, (w, h, 4) arrays.
*jiss2891 commented at 2021-03-08 20:06:38*
Hi guys, are there any plans to fix this? I'm needing this so bad..., also, is there a viable workaround to emulate this feature? I tried to use Mask but without luck, due to lack of knowledge...
I'm greyscaling an image using surfarray to manipulate the rgb values but the image has an alpha channel (it's a mob sprite), so when restored back to a surface I lost that alpha values...
*jiss2891 commented at 2021-03-09 15:24:05*
Hi again, I finally came up with a workaround to this, maybe it helps others with the same issue:
*llindstrom commented at 2021-03-09 23:46:58*
Here is a version of
pygame.pixelcopy.make_surface
for RGBA numpy arrays. Likemake_surface
, it only handles integer arrays.This could be done more cleanly using
pygame.surfarray
instead, and it would also work with floating point arrays.*jiss2891 commented at 2021-03-10 03:05:45*
That's great! I think in my case it's cheaper to access the pixel's reference, keeping the alpha intact. :)