Pillow обработка изображений в Python на примерах

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


2020-01-17 17:38

разработка по

Библиотека изображений Python, или PIL (Python Imaging Library) нужна для обработки графики в Python. Фредрик Лунд является автором одного из лучших блогов, посвященных Python. Однако он перестал обновляться в далеком 2009 году, незадолго до последнего релиза PIL. К счастью, нашлись разработчики Python, что подхватили проект, создав форк PIL под названием Pillow. Pillow стал заменой оригинальной библиотеки PIL. Он также поддерживает Python 3, чего PIL так и не достиг.

Обратите внимание на то, что PIL и Pillow не могут быть установлены одновременно. В документации есть определенные предупреждения, где перечисляются различия между PIL и Pillow. Они обновляются время от времени, поэтому лучше ознакомиться с последними изменениями на официальной странице.

Изображения которые используются в уроке:

Установка Pillow в Python

Установить Pillow в Python можно через pip или easy_install. Установка через pip выполняется следующим образом:

Shell

pip3 install pillow

1

pip3 install pillow

Обратите внимание, что при работа на Linux или Mac может потребоваться запускать команду через sudo т.е. от имени администратора.

Мы собрали ТОП Книг для Python программиста которые помогут быстро изучить язык программирования Python. Список книг: Книги по Python

Открытие изображения в Python с Pillow

image pillow python

Через Pillow можно легко открыть изображение и отобразить его на экране через внешнюю программу. Взглянем на пример:

Python

from PIL import Image image = Image.open('jelly.jpg') image.show()

1

2

3

4

from PIL import Image

image = Image.open('jelly.jpg')

image.show()

Метод show() в основном используется для отладки. В примере импортируется модуль Image и открывается указанное изображение. На Unix метод открытия сохраняет изображения во временном PPM файле и открывает его через утилиту xv. К примеру, на установленной у меня системе Linux картинка открывается через ImageMagick. На Windows изображение сохранится во временной файле BMP и откроется через простую программу вроде Paint.

Получение информации об изображении через Pillow

С помощью Pillow также можно получить подробную информацию об изображении. Рассмотрим небольшой пример:

Python

>>> from PIL import Image >>> image = Image.open('jelly.jpg') >>> r, g, b = image.split() >>> histogram = image.histogram() [384761, 489777, 557209, 405004, 220701, 154786, 55807, 35806, 21901, 16242] >>> exif = image._getexif() exif {256: 1935, 257: 3411, 271: u'Panasonic', 272: u'DMC-LX7', 274: 1, 282: (180, 1), 283: (180, 1), 296: 2, 305: u'PaintShop Pro 14.00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00', 306: u'2016:08:21 07:54:57', 36867: u'2016:08:21 07:54:57', 36868: u'2016:08:21 07:54:57', 37121: 'x01x02x03x00', 37122: (4, 1), 37381: (124, 128), 37383: 5, 37384: 0, 37385: 16, 37386: (47, 10), 40960: '0100', 40961: 1, 40962: 3968, 40963: 2232, 41495: 2, 41728: 'x03', 41729: 'x01', 41985: 0, 41986: 0, 41987: 0, 41988: (0, 10), 41989: 24, 41990: 0, 41991: 0, 41992: 0, 41993: 0, 41994: 0}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

>>> from PIL import Image

>>> image = Image.open('jelly.jpg')

>>> r, g, b = image.split()

>>> histogram = image.histogram()

[384761, 489777, 557209, 405004, 220701, 154786, 55807, 35806, 21901, 16242]

>>> exif = image._getexif()

exif

{256: 1935,

257: 3411,

271: u'Panasonic',

272: u'DMC-LX7',

274: 1,

282: (180, 1),

283: (180, 1),

296: 2,

305: u'PaintShop Pro 14.00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00',

306: u'2016:08:21 07:54:57',

36867: u'2016:08:21 07:54:57',

36868: u'2016:08:21 07:54:57',

37121: 'x01x02x03x00',

37122: (4, 1),

37381: (124, 128),

37383: 5,

37384: 0,

37385: 16,

37386: (47, 10),

40960: '0100',

40961: 1,

40962: 3968,

40963: 2232,

41495: 2,

41728: 'x03',

41729: 'x01',

41985: 0,

41986: 0,

41987: 0,

41988: (0, 10),

41989: 24,

41990: 0,

41991: 0,

41992: 0,

41993: 0,

41994: 0}

В данном примере показано, как извлечь значение RGB (red, green, blue) изображения. Также показано, как получить гистограмму изображения. Обратите внимание, что здесь вывод немного урезан, изначально он был намного больше. Вы можете построить график гистограммы, используя другой пакет Python — matplotlib.

Приведенный выше пример демонстрирует, как извлечь информацию EXIF из изображения. Опять же, здесь вывод этого метода несколько сокращен, поскольку он содержит слишком много информации, которая не имеет особого значения для статьи.

Обрезка изображений через Pillow (crop)

Pillow также можно использовать для обрезки изображения. Это довольно легкий процесс, хотя он постигается методом проб и ошибок. Попробуем обрезать нашу картинку с медузой через Image.crop():

Python

from PIL import Image image = Image.open('jelly.jpg') cropped = image.crop((0, 80, 200, 400)) cropped.save('/path/to/photos/cropped_jelly.png')

1

2

3

4

5

from PIL import Image

image = Image.open('jelly.jpg')

cropped = image.crop((0, 80, 200, 400))

cropped.save('/path/to/photos/cropped_jelly.png')

Обратите внимание, здесь просто нужно открыть изображение, после чего вызвать метод crop(). Потребуется передать координаты x/y того, что нужно обрезать, например (x1, y1, x2, y2).

В Pillow пиксель 0 является верхним левым уровнем. С увеличением значения x идет смещение вправо. С увеличением значения y идет смещение вниз. После запуска вышеуказанного кода будет получено следующее изображение:

cropped image python pillow

Довольно унылый результат. Я ведь хотел получить «голову» медузы. Для быстрого получения правильных координат можно использовать Gimp или Photoshop. Он поможет определить координаты для следующего обрезания.

Python

from PIL import Image image = Image.open('jelly.jpg') cropped = image.crop((177, 882, 1179, 1707)) cropped.save('/path/to/photos/cropped_jelly2.png')

1

2

3

4

5

from PIL import Image

image = Image.open('jelly.jpg')

cropped = image.crop((177, 882, 1179, 1707))

cropped.save('/path/to/photos/cropped_jelly2.png')

При запуске кода результатом станет следующее обрезанное изображение:

cropped image python pillow

Намного лучше!

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

Поворачивание изображения — метод rotate() Pillow

Image.rotate() возвращает развернутую копию изображения.

Python

from PIL import Image import sys try: tatras = Image.open("tatras.jpg") except IOError: print("Unable to load image") sys.exit(1) rotated = tatras.rotate(180) rotated.save('tatras_rotated.jpg')

1

2

3

4

5

6

7

8

9

10

11

from PIL import Image

import sys

try:

    tatras = Image.open("tatras.jpg")

except IOError:

    print("Unable to load image")

    sys.exit(1)

rotated = tatras.rotate(180)

rotated.save('tatras_rotated.jpg')

Данная программа поворачивает изображения на 180 градусов и сохраняет файл результат в виде новой картинки на диск.

Отображение картинки в Tkinter Python

Следующий код нужен для отображения картинки в программе Tkinter.

Python

#!/usr/bin/python3 # -*- coding: utf-8 -*- from PIL import Image, ImageTk from tkinter import Tk from tkinter.ttk import Frame, Label import sys class Example(Frame): def __init__(self): super().__init__() self.loadImage() self.initUI() def loadImage(self): try: self.img = Image.open("tatrs.jpg") except IOError: print("Unable to load image") sys.exit(1) def initUI(self): self.master.title("Label") tatras = ImageTk.PhotoImage(self.img) label = Label(self, image=tatras) # reference must be stored label.image = tatras label.pack() self.pack() def setGeometry(self): w, h = self.img.size self.master.geometry(("%dx%d+300+300") % (w, h)) def main(): root = Tk() ex = Example() ex.setGeometry() root.mainloop() if __name__ == '__main__': main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

#!/usr/bin/python3

# -*- coding: utf-8 -*-

from PIL import Image, ImageTk

from tkinter import Tk

from tkinter.ttk import Frame, Label

import sys

class Example(Frame):

    def __init__(self):

        super().__init__()  

        self.loadImage()

        self.initUI()

    def loadImage(self):

        try:

            self.img = Image.open("tatrs.jpg")

        except IOError:

            print("Unable to load image")

            sys.exit(1)

    def initUI(self):

        self.master.title("Label")

        tatras = ImageTk.PhotoImage(self.img)

        label = Label(self, image=tatras)

        # reference must be stored

        label.image = tatras

        label.pack()

        self.pack()

    def setGeometry(self):

        w, h = self.img.size

        self.master.geometry(("%dx%d+300+300") % (w, h))

def main():

    root = Tk()

    ex = Example()

    ex.setGeometry()

    root.mainloop()  

if __name__ == '__main__':

    main()

Программа показывает картинку в виджет label тулкит от Tkinter.

Python

from PIL import Image, ImageTk

1

from PIL import Image, ImageTk

ImageTk является изображением, совместимым с Tkinter. Может использоваться везде, где Tkinter ожидает получения объекта изображения.

Python

tatras = ImageTk.PhotoImage(self.img)

1

tatras = ImageTk.PhotoImage(self.img)

Здесь мы создаем изображение.

Python

label = Label(self, image=tatras)

1

label = Label(self, image=tatras)

Изображению передаются параметру image виджета label.

Python

label.image = tatras

1

label.image = tatras

Во избежание скапливания мусора отсылки на изображения должны сохраняться.

Python

w, h = self.img.size self.master.geometry(("%dx%d+300+300") % (w, h))

1

2

w, h = self.img.size

self.master.geometry(("%dx%d+300+300") % (w, h))

Размер окна совпадает с размером изображения.

Загрузка изображения из URL в Pillow

В следующем примере показано, как получить изображение, указав его URL адрес.

Python

from PIL import Image import requests import sys url = 'https://i.ytimg.com/vi/vEYsdh6uiS4/maxresdefault.jpg' try: resp = requests.get(url, stream=True).raw except requests.exceptions.RequestException as e: sys.exit(1) try: img = Image.open(resp) except IOError: print("Unable to open image") sys.exit(1) img.save('sid.jpg', 'jpeg')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

from PIL import Image

import requests

import sys

url = '

'

try:

    resp = requests.get(url, stream=True).raw

except requests.exceptions.RequestException as e:  

    sys.exit(1)

try:

    img = Image.open(resp)

except IOError:

    print("Unable to open image")

    sys.exit(1)

img.save('sid.jpg', 'jpeg')

Код читает изображение через его URL и сохраняет его на диск.

Python

import requests

1

import requests

Мы используем библиотеку requests для загрузки изображения.

Python

resp = requests.get(url, stream=True).raw

1

resp = requests.get(url, stream=True).raw

Изображение читается как данные raw.

Python

img = Image.open(resp)

1

img = Image.open(resp)

Картинка создается из ответного объекта response.

Python

img.save('sid.jpg', 'jpeg')

1

img.save('sid.jpg', 'jpeg')

И в конечном итоге изображение сохраняется.

Создание рисунка в Pillow

У Pillow есть базовые возможности для создания 2D графики. Модуль ImageDraw предоставляет простую 2D графику для объектов Image. Мы можем создавать новые изображения, аннотации к ним, ретушировать существующие фото, а также сразу генерировать графику для веб.

Python

from PIL import Image, ImageDraw # Создаем белый квадрат img = Image.new('RGBA', (200, 200), 'white') idraw = ImageDraw.Draw(img) idraw.rectangle((10, 10, 100, 100), fill='blue') img.save('rectangle.png')

1

2

3

4

5

6

7

8

9

from PIL import Image, ImageDraw

# Создаем белый квадрат

img = Image.new('RGBA', (200, 200), 'white')    

idraw = ImageDraw.Draw(img)

idraw.rectangle((10, 10, 100, 100), fill='blue')

img.save('rectangle.png')

В примере создается новое изображение, на котором нарисован голубой прямоугольник поверх белого фона.

Python

img = Image.new('RGBA', (200, 200), 'white')

1

img = Image.new('RGBA', (200, 200), 'white')

Создается новое изображение, у которого режим «RGBA», размер 200х200 и белый фон.

Python

idraw = ImageDraw.Draw(img)

1

idraw = ImageDraw.Draw(img)

Из картинки создается объект ImageDraw. Теперь на нем можно что-то нарисовать.

Python

idraw.rectangle((10, 10, 100, 100), fill='blue')

1

idraw.rectangle((10, 10, 100, 100), fill='blue')

С помощью метода rectangle() на площади созданного изображения мы нарисовали голубой прямоугольник.

ImageFont — Пишем текст на изображение используя Pillow

В следующем коде показано, как в Python можно написать текст на изображении с помощью Pillow.

На сайте есть отдельная статья по нанесению водяного знака на изображение:

  1. Как ставить водяные знаки на изображениях при помощи Python

Python

from PIL import Image, ImageDraw, ImageFont import sys try: tatras = Image.open("tatras.jpg") except: print("Unable to load image") sys.exit(1) idraw = ImageDraw.Draw(tatras) text = "High Tatras" font = ImageFont.truetype("arial.ttf", size=18) idraw.text((10, 10), text, font=font) tatras.save('tatras_watermarked.png')

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

from PIL import Image, ImageDraw, ImageFont

import sys

try:

    tatras = Image.open("tatras.jpg")

except:

    print("Unable to load image")

    sys.exit(1)

idraw = ImageDraw.Draw(tatras)

text = "High Tatras"

font = ImageFont.truetype("arial.ttf", size=18)

idraw.text((10, 10), text, font=font)

tatras.save('tatras_watermarked.png')

Для создания рисунка используется модуль ImageDraw.

Python

font = ImageFont.truetype("arial.ttf", size=18)

1

font = ImageFont.truetype("arial.ttf", size=18)

Создается шрифт Arial с размером 18.

Python

idraw.text((10, 10), text, font=font)

1

idraw.text((10, 10), text, font=font)

Сам текст наносится через метод text(). По умолчанию цвет шрифта белый.

Pillow текст на изображение Pillow

Использование фильтров в Pillow

фильтры python pillow

Оригинальное изображение с медузой

Pillow позволяет использовать множество различных фильтров для обработки изображения. Они являются частью модуля ImageFilter. Давайте рассмотрим несколько примеров использования метода filter():

Python

from PIL import ImageFilter from PIL import Image image = Image.open('jelly.jpg') blurred_jelly = image.filter(ImageFilter.BLUR) blurred_jelly.save('/path/to/photos/blurry_jelly.png')

1

2

3

4

5

6

from PIL import ImageFilter

from PIL import Image

image = Image.open('jelly.jpg')

blurred_jelly = image.filter(ImageFilter.BLUR)

blurred_jelly.save('/path/to/photos/blurry_jelly.png')

Программа берет определенное изображение, создает на его основе размытую картинку, используя ImageFilter.BLUR, и сохраняет полученный результат на диск с помощью метода save(). Итоговое фото со слегка размытой медузой:

фильтр размытия pillow python

Размытая картинка с медузой

Однако в подобающем большинстве случаев размывать изображение нет нужды, наоборот — требуется увеличить резкость. Pillow меняет резкость картинки следующим образом:

Python

from PIL import ImageFilter from PIL import Image image = Image.open('/path/to/photos/jelly.jpg') blurred_jelly = image.filter(ImageFilter.SHARPEN) blurred_jelly.save('/path/to/photos/sharper_jelly.png')

1

2

3

4

5

6

from PIL import ImageFilter

from PIL import Image

image = Image.open('/path/to/photos/jelly.jpg')

blurred_jelly = image.filter(ImageFilter.SHARPEN)

blurred_jelly.save('/path/to/photos/sharper_jelly.png')

Результат после запуска кода выше:

фильтр резкости pillow python

Картинка с медузой после применения фильтра резкости

Кроме того, для увеличения резкости фотографий в Python можно использовать модуль ImageEnhance.

Можно использовать и другие фильтры — DETAIL, EDGE_ENHANCE, EMBOSS, SMOOTH и так далее. В коде для одного изображения также можно одновременно использовать несколько фильтров.

Для сравнения эффектов от использования фильтров можете скачать изображения, которые были представлены в примерах выше.

Конвертирование из JPG в PNG пример Pillow

В Python Pillow метод save() позволяет конвертировать изображение в другой формат.

Python

from PIL import Image import sys try: tatras = Image.open("tatras.jpg") except IOError: print("Unable to load image") sys.exit(1) tatras.save('tatras.png', 'png')

1

2

3

4

5

6

7

8

9

10

from PIL import Image

import sys

try:

    tatras = Image.open("tatras.jpg")

except IOError:

    print("Unable to load image")

    sys.exit(1)

tatras.save('tatras.png', 'png')

Программа считывает изображение JPG и конвертирует его в PNG формат. Это делает в следующей строчке:

Python

tatras.save('tatras.png', 'png')

1

tatras.save('tatras.png', 'png')

Второй параметр метода save() нужен для уточнения итогового формата изображения.

Создаем черно-белое изображение GrayScale в Pillow

С помощью метода Image.convert() можно сделать оригинальное изображение черно-белым.

Python

from PIL import Image import sys try: tatras = Image.open("tatras.jpg") except IOError: print("Unable to load image") sys.exit(1) grayscale = tatras.convert('L') grayscale.show()

1

2

3

4

5

6

7

8

9

10

11

from PIL import Image

import sys

try:

    tatras = Image.open("tatras.jpg")

except IOError:

    print("Unable to load image")

    sys.exit(1)

grayscale = tatras.convert('L')

grayscale.show()

Программа читает изображение и трансформирует его в черно-белое. За это отвечает следующая строка:

Python

grayscale = tatras.convert('L')

1

grayscale = tatras.convert('L')

Первый параметр метода convert() является модом. Мод 'L' представляет черно-белый вариант.

Изменение размера изображения в Pillow resize()

Можно изменить длину и ширину изображения при помощи метода resize(). В данном примере будут показаны три примера изменения размера:

  • Изменение размера изображения имея ширину и высоту;
  • Изменение ширины с учетом пропорций для высоты;
  • Изменение высоты пропорционально ширине.

Изменение размера изображения имея ширину и высоту

Python

from PIL import Image # Меняем размер изображения на новый. tatras = Image.open("tatras.jpg") tatras = tatras.resize((100, 100), Image.ANTIALIAS)

1

2

3

4

5

from PIL import Image

# Меняем размер изображения на новый.

tatras = Image.open("tatras.jpg")

tatras = tatras.resize((100, 100), Image.ANTIALIAS)

Изменение ширины с учетом пропорций для новой высоты изображения

Python

from PIL import Image tatras = Image.open("tatras.jpg") new_width = 680 # ширина new_height = int(new_width * height / width) tatras = tatras.resize((new_width, new_height), Image.ANTIALIAS) tatras.show()

1

2

3

4

5

6

7

8

9

from PIL import Image

tatras = Image.open("tatras.jpg")

new_width  = 680 # ширина

new_height = int(new_width * height / width)

tatras = tatras.resize((new_width, new_height), Image.ANTIALIAS)

tatras.show()

Изменение высоты изображения, пропорционально обновляем и ширину

Python

from PIL import Image tatras = Image.open("tatras.jpg") new_height = 680 # Высота new_width = int(new_height * width / height) tatras = tatras.resize((new_width, new_height), Image.ANTIALIAS) tatras.show()

1

2

3

4

5

6

7

8

9

from PIL import Image

tatras = Image.open("tatras.jpg")

new_height = 680 # Высота

new_width  = int(new_height * width / height)

tatras = tatras.resize((new_width, new_height), Image.ANTIALIAS)

tatras.show()

Заключение

С пакетом Pillow вы можете сделать гораздо больше, чем описано в этой короткой статье. Pillow поддерживает преобразования и улучшение изображений, возможность печати фото и многое другое. Я настоятельно рекомендую прочитать документацию Pillow, чтобы получить полное представление обо всем, что вы можете сделать.


Источник: python-scripts.com

Комментарии: