Как инвертировать цвета изображения с помощью PIL (Python-Imaging)?

Мне нужно преобразовать серию изображений, нарисованных белыми буквами на черном фоне, в изображения, где белый и черный инвертированы (как отрицательные). Как я могу добиться этого с помощью PIL?


person bialix    schedule 23.03.2010    source источник


Ответы (4)


Попробуйте следующее из документации: http://effbot.org/imagingbook/imageops.htm.

from PIL import Image
import PIL.ImageOps    

image = Image.open('your_image.png')

inverted_image = PIL.ImageOps.invert(image)

inverted_image.save('new_name.png')

Примечание. «Модуль ImageOps содержит ряд «готовых» операций обработки изображений. Этот модуль несколько экспериментальный, и большинство операторов работают только с изображениями L и RGB».

person Gary Kerr    schedule 23.03.2010
comment
О, кажется, я пропустил этот модуль. Спасибо. - person bialix; 23.03.2010
comment
да, но некоторые реализации PIL не будут работать с изображениями с режимами, отличными от RGB и L (т.е. RGBA, CMYK, 1), и в этом случае вам придется использовать обходные пути, которые преобразуют полосы исходного изображения в изображения L, затем инвертируют их, а затем объединяют. снова вместе (см. ниже). - person mxl; 30.06.2019
comment
модуль «PIL» не имеет атрибута «ImageOps» - person Yaroslav Dukal; 13.07.2019

Если изображение прозрачно RGBA, это не удастся... Это должно работать:

from PIL import Image
import PIL.ImageOps    

image = Image.open('your_image.png')
if image.mode == 'RGBA':
    r,g,b,a = image.split()
    rgb_image = Image.merge('RGB', (r,g,b))

    inverted_image = PIL.ImageOps.invert(rgb_image)

    r2,g2,b2 = inverted_image.split()

    final_transparent_image = Image.merge('RGBA', (r2,g2,b2,a))

    final_transparent_image.save('new_file.png')

else:
    inverted_image = PIL.ImageOps.invert(image)
    inverted_image.save('new_name.png')
person Dave    schedule 14.10.2012
comment
Хорошо, но это НЕ включает альфа-канал для инверсии. Что, если я хочу также инвертировать альфа-канал? - person AgentM; 17.10.2019
comment
Такой старый ответ и до сих пор работает как шарм. Спасибо чувак! - person Aniket Betkikar; 18.09.2020

Для тех, кто работает с изображением в режиме «1» (т. е. 1-битные пиксели, черно-белые, сохраненные с одним пикселем на байт — см. документы), перед вызовом PIL.ImageOps.invert необходимо преобразовать его в режим "L".

Таким образом:

im = im.convert('L')
im = ImageOps.invert(im)
im = im.convert('1')
person Greg Sadetsky    schedule 14.07.2016
comment
Я бы хотел, чтобы был способ просто указать другие методы, которые используют такие вещи, как маски для инвертирования, вместо такого обходного пути... но да ладно, пока это работает! - person nmz787; 06.06.2020

В случае, если кто-то инвертирует изображение CMYK, текущие реализации PIL и Pillow, похоже, не поддерживают это и выдают ошибку. Однако вы можете легко обойти эту проблему, инвертируя отдельные полосы вашего изображения, используя эту удобную функцию (по сути, расширение сообщения Грега Садецки выше):

def CMYKInvert(img) :
    return Image.merge(img.mode, [ImageOps.invert(b.convert('L')) for b in img.split()])
person mxl    schedule 08.06.2018