Open itzpr3d4t0r opened 1 week ago
I agree, this sounds like a very useful feature. I personally think it would be a better fit as an in place surface method in line with set_at or fill (that returns the surface because I think new methods should do that, or not if we want to keep consistency with the rest of the methods). I can literally remember an old project of mine where this feature would have saved me the get/set_at slow loop, so I vibe with it a lot.
This already exists? https://pyga.me/docs/ref/pixelarray.html#pygame.PixelArray.replace
Didn't see that coming but it doesn't allow you to change more than one color per call (which tbh is a more realistic usecase), that means that it will run trhough the surface pixels N times instead of one with a better implementation.
Like I've compared this function using PixelArray to replace 3 colors with my custom avx implementation and these are the results:
def py_replace_colors_PixelArray(surface, colors):
arr = PixelArray(surface)
for old, new in colors:
arr.replace(old, new)
arr.close()
I believe this to be more convenient, but if it's really a burden to add more functionality to surface or transform we could expand Pixelarray.replace to support multiple colors.
With the recent addition of
transform.hsl()
(#2398) we now have 5 ways to interact with pixels from a surface, that are:Surface.get_at()
/Surface.set_at()
Surface.blit()
with different blend flagstransform.hsl()
Surface.fill()
While these options cover most needs, there's still room for improvement. Specifically, there's no built-in, easy, and fast way to replace all occurrences of one color with another on a surface:
These methods either compromise performance, ease of use or miss the point completely. Therefore, I propose adding a new method/function that can replace a set of colors with another set of corresponding colors:
Surface.replace_colors(sequence: Sequence[Tuple[ColorValue, ColorValue]])
pygame.transform.replace_colors(sequence: Sequence[Tuple[ColorValue, ColorValue]], dest: Optional[Surface] = None)
So you could have something like this:
Which could be a really cool addition to quickly change the look of your sprites and an easy way.
My internal tests show that a custom C implementation of this feature would be:
There have also been discussions about the need for these operations, indicating a genuine demand for such a feature: https://discord.com/channels/772505616680878080/1245854714504024104