How to invert colors of an image in pygame?

故事扮演 提交于 2019-12-23 07:56:39

问题


I have a pygame Surface and would like to invert the colors. Is there any way quicker & more pythonic than this? It's rather slow.

I'm aware that subtracting the value from 255 isn't the only definition of an "inverted color," but it's what I want for now.

I'm surprised that pygame doesn't have something like this built in!

Thanks for your help!

import pygame

def invertImg(img):
    """Inverts the colors of a pygame Screen"""

    img.lock()

    for x in range(img.get_width()):
        for y in range(img.get_height()):
            RGBA = img.get_at((x,y))
            for i in range(3):
                # Invert RGB, but not Alpha
                RGBA[i] = 255 - RGBA[i]
            img.set_at((x,y),RGBA)

    img.unlock()

回答1:


Winston's answer is nice, but for the sake of completeness, when one has to manipulate an image pixel-by-pixel in Python, one should avoid looping through every pixel, no matter which image library is in use. This is CPU-intensive due to the nature of the language, and can rarely be made to work in realtime.

Fortunately, the excellent NumPy library can help perform several scalar operations in streams of bytes, looping over each number in native code, which is orders of magnitude faster than doing it solely in Python. For this particular operation, if we use an xor operation with (2^32 - 1), we can delegate the operation to the inner loop in native code.

This example, which you can paste directly into your Python console, will flip the pixels instantly to white (if you have NumPy installed):

import pygame

srf = pygame.display.set_mode((640,480))
pixels = pygame.surfarray.pixels2d(srf)
pixels ^= 2 ** 32 - 1
del pixels

pygame.display.flip()

Without NumPy installed, pygame.surfarray methods return ordinary Python arrays (from the stdlib array module) and you would have to find another way to operate on these numbers, since the ordinary Python array does not operate on all elements when a line such as pixels ^= 2 ** 32 - 1 is given.




回答2:


Taken from: http://archives.seul.org/pygame/users/Sep-2008/msg00142.html

def inverted(img):
   inv = pygame.Surface(img.get_rect().size, pygame.SRCALPHA)
   inv.fill((255,255,255,255))
   inv.blit(img, (0,0), None, BLEND_RGB_SUB)
   return inv

This may do the alpha channel wrong, but you should be able to get that working with additional tweaks.




回答3:


One approach that might be more efficient would be to use PIL, as described here: How to invert colors of image with PIL (Python-Imaging)?

It's easy to convert it to a native pygame image in-memory, as described here: http://mail.python.org/pipermail/image-sig/2005-May/003315.html



来源:https://stackoverflow.com/questions/5891808/how-to-invert-colors-of-an-image-in-pygame

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