Как инвертировать цвета изображения в Pygame? - PullRequest
7 голосов
/ 05 мая 2011

У меня есть поверхность Pygame, и я хотел бы инвертировать цвета.Есть ли способ быстрее и питоннее, чем этот?Это довольно медленно.

Я знаю, что вычитание значения из 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()

Ответы [ 3 ]

8 голосов
/ 05 мая 2011

Взято из: 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

Это может неправильно работать с альфа-каналом, но вы должны иметь возможность работать с дополнительными настройками.

6 голосов
/ 05 мая 2011

Ответ Уинстона хорош, но для полноты картины, когда нужно манипулировать изображением попиксельно в Python, нужно избегать циклического прохождения каждого пикселя, независимо от того, какая библиотека изображений используется. Это сильно загружает процессор из-за особенностей языка, и его редко можно заставить работать в реальном времени.

К счастью, отличная библиотека 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 (из модуля массива stdlib), и вам придется искать другой способ работы с этими числами, поскольку обычный массив Python не работает со всеми элементами, когда дается строка, такая как pixels ^= 2 ** 32 - 1.

1 голос
/ 05 мая 2011

Один из подходов, который может быть более эффективным, - это использовать PIL , как описано здесь: Как инвертировать цвета изображения с помощью PIL (Python-Imaging)?

Легко преобразовать его в собственное изображение Pygame в памяти, как описано здесь: http://mail.python.org/pipermail/image-sig/2005-May/003315.html

...