Как использовать библиотеку PIL для обработки изображений?

Библиотека PIL (Python Imaging Library) — одна из самых популярных и простых в использовании библиотек для обработки изображений на языке Python. Хотя оригинальная PIL давно не поддерживается, её форк — Pillow — активно развивается и используется в современных проектах.

PIL/Pillow предоставляет широкий набор функций: открытие, сохранение, изменение размеров, повороты, фильтры, работа с каналами, рисование и многое другое.

Установка

pip install Pillow

Импортируется как:

from PIL import Image

Открытие и сохранение изображений

from PIL import Image
img = Image.open("example.jpg") # Открытие
img.save("output.png") # Сохранение в другом формате

Поддерживаются многие форматы: JPEG, PNG, BMP, TIFF, GIF и др.

Проверка формата и размера:

print(img.format) # 'JPEG'

print(img.size) # (ширина, высота)

print(img.mode) # 'RGB', 'L', 'RGBA', и т.д.

Изменение размера

resized = img.resize((200, 200)) # Жёсткое масштабирование
resized = img.thumbnail((200, 200)) # Пропорциональное уменьшение

Метод thumbnail изменяет изображение на месте и сохраняет пропорции.

Обрезка (Crop)

\# Обрезать прямоугольник (левая, верхняя, правая, нижняя)
cropped = img.crop((100, 100, 300, 300))

Поворот и отражение

rotated = img.rotate(90) # По часовой стрелке
flipped = img.transpose(Image.FLIP_LEFT_RIGHT) # Горизонтальное отражение

Дополнительно:

  • Image.FLIP_TOP_BOTTOM

  • Image.ROTATE_90, Image.ROTATE_180, Image.ROTATE_270

Преобразование цветового пространства

gray = img.convert("L") # В оттенки серого
rgba = img.convert("RGBA") # Добавить альфа-канал

Работа с пикселями

Получение и установка одного пикселя:

r, g, b = img.getpixel((50, 50))
img.putpixel((50, 50), (255, 0, 0)) # Сделать пиксель красным

Применение фильтров

from PIL import ImageFilter
blurred = img.filter(ImageFilter.BLUR)
sharpened = img.filter(ImageFilter.SHARPEN)
contour = img.filter(ImageFilter.CONTOUR)

Другие фильтры:

  • DETAIL

  • EDGE_ENHANCE

  • SMOOTH

  • EMBOSS

  • FIND_EDGES

Работа с альфа-каналом и прозрачностью

img = img.convert("RGBA")
r, g, b, a = img.split()
\# Установить прозрачность всех пикселей
a = a.point(lambda i: i // 2)
img = Image.merge("RGBA", (r, g, b, a))  

Слияние изображений

img1 = Image.open("bg.png").convert("RGBA")
img2 = Image.open("overlay.png").convert("RGBA")
combined = Image.alpha_composite(img1, img2)

Или простое вставление:

img1.paste(img2, (50, 50)) # Вставка без альфа-канала

Если img2 с альфа-каналом:

img1.paste(img2, (50, 50), img2)

Рисование на изображении

from PIL import ImageDraw, ImageFont
img = Image.new("RGB", (400, 300), (255, 255, 255))
draw = ImageDraw.Draw(img)
draw.rectangle(\[50, 50, 150, 150\], outline="blue", width=3)
draw.ellipse(\[200, 50, 300, 150\], fill="red")
draw.line((0, 0, 400, 300), fill="green", width=5)
\# Добавление текста
font = ImageFont.truetype("arial.ttf", size=24)
draw.text((50, 200), "Привет, PIL!", font=font, fill="black")

Применение точечных преобразований

inverted = img.point(lambda p: 255 - p) # Инверсия цвета
brighter = img.point(lambda p: p \* 1.2) # Ярче (может выйти за пределы 255)

Маскирование и маски

Маска — это изображение в оттенках серого, где чёрный = прозрачный, белый = непрозрачный.

mask = Image.open("mask.png").convert("L")
img.paste(overlay, (0, 0), mask)

Создание нового изображения

new_img = Image.new("RGB", (300, 300), (255, 255, 255)) # Белый фон

Сравнение с NumPy

PIL и NumPy могут работать вместе:

import numpy as np
arr = np.array(img) # PIL → NumPy
img2 = Image.fromarray(arr) # NumPy → PIL

Это позволяет выполнять низкоуровневую обработку с помощью NumPy (например, фильтрацию, арифметику над изображениями) и визуализацию с помощью PIL.

Сохранение с параметрами

JPEG с разным качеством:

img.save("out.jpg", "JPEG", quality=85)

PNG с прозрачностью:

img.save("out.png", "PNG", optimize=True)  

Работа с анимацией (GIF)

Открытие и разбор кадров GIF:

gif = Image.open("animation.gif")
for frame in range(gif.n_frames):
gif.seek(frame)
gif.save(f"frame_{frame}.png")

Создание анимированного GIF:

frames = \[Image.open(f"frame_{i}.png") for i in range(5)\]
frames\[0\].save("out.gif", save_all=True, append_images=frames\[1:\], duration=200, loop=0)

Пример комплексной обработки

from PIL import Image, ImageFilter, ImageDraw
img = Image.open("input.jpg").convert("RGB")
img = img.resize((300, 300))
img = img.rotate(30)
img = img.filter(ImageFilter.EDGE_ENHANCE)
draw = ImageDraw.Draw(img)
draw.rectangle((50, 50, 250, 250), outline="blue", width=3)
img.save("processed.jpg")

Расширенные возможности Pillow

  • Поддержка EXIF-метаданных: img._getexif()

  • Чтение из потоков (например, BytesIO)

  • Работа с цветами, гамма-коррекцией, палитрами

  • Поддержка CMYK, LAB, HSV

PIL (в виде Pillow) остаётся универсальным инструментом для скриптовой и прикладной обработки изображений, благодаря своей простоте, совместимости и широким возможностям.