10

我有一个 pygame Surface 并且想反转颜色。有没有比这更快、更 Pythonic 的方法?它比较慢。

我知道从 255 中减去该值并不是“反转颜色”的唯一定义,但这是我现在想要的。

我很惊讶 pygame 没有内置这样的东西!

谢谢你的帮助!

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()
4

3 回答 3

10

取自: 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

这可能会使 alpha 通道出错,但您应该能够通过额外的调整来解决这个问题。

于 2011-05-05T02:13:31.977 回答
7

Winston 的回答很好,但为了完整起见,当必须在 Python 中逐个像素地操作图像时,无论使用哪个图像库,都应该避免遍历每个像素。由于语言的性质,这是 CPU 密集型的,并且很少可以实时工作。

幸运的是,优秀的NumPy库可以帮助在字节流中执行多个标量操作,在本机代码中循环每个数字,这比仅在 Python 中执行要快几个数量级。对于这个特定的操作,如果我们使用带有 的xor操作(2^32 - 1),我们可以将操作委托给本机代码中的内部循环。

这个例子,你可以直接粘贴到你的 Python 控制台,会立即将像素翻转为白色(如果你安装了 NumPy):

import pygame

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

pygame.display.flip()

如果没有安装 NumPy,pygame.surfarray方法会返回普通的 Python 数组(来自stdlibarray 模块),你必须找到另一种方法来操作这些数字,因为当给定一行时,普通的 Python 数组不会对所有元素进行操作pixels ^= 2 ** 32 - 1

于 2011-05-05T02:28:04.953 回答
1

一种可能更有效的方法是使用PIL,如下所述:如何使用 PIL (Python-Imaging) 反转图像颜色?

很容易将其转换为内存中的原生 pygame 图像,如下所述:http: //mail.python.org/pipermail/image-sig/2005-May/003315.html

于 2011-05-05T01:57:16.103 回答