Основы работы с библиотекой Pillow в Python
Работа с изображениями является неотъемлемой частью современной разработки программного обеспечения. От создания веб-приложений с динамической генерацией контента до разработки систем компьютерного зрения и машинного обучения — везде требуются инструменты для обработки графических данных. Библиотека Pillow (Python Imaging Library) представляет собой мощное и универсальное решение для работы с изображениями в экосистеме Python.
Pillow является активно развиваемым форком оригинальной библиотеки PIL, которая была создана в 1995 году Фредериком Лундом. После прекращения разработки PIL в 2011 году, Алекс Кларк и сообщество разработчиков создали Pillow, обеспечив совместимость с оригинальным API и добавив множество новых возможностей и улучшений.
Основные преимущества Pillow включают простоту использования, обширную поддержку графических форматов, богатый набор инструментов для редактирования и анализа изображений, а также активную поддержку сообщества. Библиотека широко используется в веб-разработке, научных вычислениях, машинном обучении и автоматизации графических процессов.
О библиотеке Pillow
История и развитие
Pillow была создана как форк PIL (Python Imaging Library) с целью обеспечения совместимости с Python 3 и устранения проблем с установкой оригинальной библиотеки. Название "Pillow" происходит от английского слова "подушка" и является игрой слов с аббревиатурой PIL.
Библиотека активно развивается с 2010 года и поддерживается большим сообществом разработчиков. Регулярные обновления включают поддержку новых форматов изображений, улучшения производительности, исправления безопасности и расширение функциональности.
Архитектура и принципы работы
Pillow построена на принципах объектно-ориентированного программирования. Центральным элементом является класс Image, который представляет изображение в памяти. Все операции с изображениями выполняются через методы этого класса или связанных с ним модулей.
Библиотека поддерживает ленивые вычисления (lazy evaluation), что означает, что многие операции не выполняются немедленно, а откладываются до момента сохранения или явного вызова. Это позволяет оптимизировать цепочки преобразований и повышает производительность.
Основные модули и компоненты
Pillow состоит из нескольких ключевых модулей:
- Image — основной модуль для работы с изображениями
- ImageDraw — модуль для рисования примитивов и текста
- ImageFilter — набор предустановленных фильтров
- ImageEnhance — инструменты для улучшения качества изображений
- ImageFont — работа со шрифтами
- ImageColor — утилиты для работы с цветами
- ImageOps — дополнительные операции с изображениями
Установка и настройка
Стандартная установка
pip install pillow
Установка с дополнительными зависимостями
Для расширенной функциональности можно установить дополнительные библиотеки:
pip install pillow[imaging] # Дополнительные кодеки
pip install pillow[extra] # Все дополнительные зависимости
Проверка установки
from PIL import Image
import PIL
print(PIL.__version__)
print(PIL.features.check_feature('webp')) # Проверка поддержки WebP
Основные операции с изображениями
Открытие и базовая информация об изображениях
from PIL import Image
# Открытие изображения
img = Image.open("example.jpg")
# Получение основной информации
print(f"Формат: {img.format}")
print(f"Размер: {img.size}")
print(f"Цветовой режим: {img.mode}")
print(f"Информация о файле: {img.info}")
Сохранение изображений
# Простое сохранение
img.save("output.png")
# Сохранение с настройками качества
img.save("compressed.jpg", quality=85, optimize=True)
# Сохранение в разных форматах
img.save("output.webp", "WEBP", quality=80)
img.save("output.bmp", "BMP")
Изменение размеров и геометрические преобразования
# Изменение размера с сохранением пропорций
img_resized = img.resize((300, 300))
# Изменение размера с указанием алгоритма ресемплинга
img_high_quality = img.resize((800, 600), Image.LANCZOS)
# Поворот изображения
rotated_45 = img.rotate(45, expand=True) # expand=True увеличивает холст
rotated_90 = img.rotate(90)
# Обрезка изображения (левый верхний x, левый верхний y, правый нижний x, правый нижний y)
cropped = img.crop((100, 100, 400, 400))
# Отражения
flipped_horizontal = img.transpose(Image.FLIP_LEFT_RIGHT)
flipped_vertical = img.transpose(Image.FLIP_TOP_BOTTOM)
Конвертация цветовых моделей и форматов
# Конвертация в градации серого
grayscale = img.convert("L")
# Конвертация в RGBA (с альфа-каналом)
rgba_img = img.convert("RGBA")
# Конвертация в CMYK для печати
cmyk_img = img.convert("CMYK")
# Конвертация в палитровое изображение
palette_img = img.convert("P")
Создание и рисование изображений
Создание новых изображений
from PIL import Image, ImageDraw, ImageFont
# Создание пустого изображения
blank_img = Image.new("RGB", (500, 300), color=(255, 255, 255))
# Создание изображения с градиентом
gradient = Image.new("RGB", (400, 400))
pixels = gradient.load()
for x in range(400):
for y in range(400):
pixels[x, y] = (x % 256, y % 256, (x + y) % 256)
Рисование примитивов и текста
# Создание объекта для рисования
draw = ImageDraw.Draw(blank_img)
# Рисование различных фигур
draw.line([(0, 0), (500, 300)], fill=(255, 0, 0), width=3)
draw.rectangle([50, 50, 200, 150], fill=(0, 255, 0), outline=(0, 0, 255))
draw.ellipse([250, 100, 400, 200], fill=(255, 255, 0))
# Загрузка шрифта и добавление текста
try:
font = ImageFont.truetype("arial.ttf", 40)
except OSError:
font = ImageFont.load_default()
draw.text((10, 60), "Привет, мир!", font=font, fill=(0, 0, 0))
Применение фильтров и улучшений
Использование встроенных фильтров
from PIL import ImageFilter, ImageEnhance
# Применение различных фильтров
blurred = img.filter(ImageFilter.GaussianBlur(radius=5))
sharpened = img.filter(ImageFilter.SHARPEN)
edges = img.filter(ImageFilter.FIND_EDGES)
embossed = img.filter(ImageFilter.EMBOSS)
# Создание собственного фильтра
custom_filter = ImageFilter.Kernel((3, 3), [-1, -1, -1, -1, 9, -1, -1, -1, -1])
custom_filtered = img.filter(custom_filter)
Улучшение качества изображений
# Настройка яркости
brightness_enhancer = ImageEnhance.Brightness(img)
brighter_img = brightness_enhancer.enhance(1.5) # Увеличить яркость на 50%
# Настройка контрастности
contrast_enhancer = ImageEnhance.Contrast(img)
contrasted_img = contrast_enhancer.enhance(2.0)
# Настройка цветовой насыщенности
color_enhancer = ImageEnhance.Color(img)
saturated_img = color_enhancer.enhance(1.5)
# Настройка резкости
sharpness_enhancer = ImageEnhance.Sharpness(img)
sharp_img = sharpness_enhancer.enhance(2.0)
Работа со сложными изображениями
Слияние и композиция изображений
# Наложение изображений
background = Image.open("bg.jpg").convert("RGBA")
overlay = Image.open("logo.png").convert("RGBA")
# Простое наложение
background.paste(overlay, (50, 50), overlay)
# Создание маски для сложного наложения
mask = Image.new("L", overlay.size, 128) # Полупрозрачная маска
background.paste(overlay, (100, 100), mask)
# Альфа-композиция
blended = Image.alpha_composite(background, overlay)
Создание и работа с анимированными GIF
# Создание анимации из последовательности изображений
frames = []
for i in range(10):
frame = Image.new("RGB", (200, 200), color=(i*25, 100, 200-i*20))
draw = ImageDraw.Draw(frame)
draw.ellipse([50+i*5, 50+i*5, 150+i*5, 150+i*5], fill=(255, 255, 0))
frames.append(frame)
# Сохранение анимации
frames[0].save(
"animated.gif",
save_all=True,
append_images=frames[1:],
duration=300,
loop=0
)
Продвинутая работа с пикселями
import numpy as np
# Преобразование в массив NumPy для быстрой обработки
img_array = np.array(img)
# Инвертирование цветов через NumPy
inverted_array = 255 - img_array
inverted_img = Image.fromarray(inverted_array)
# Прямая работа с пикселями (медленнее, но более контролируемо)
pixels = img.load()
width, height = img.size
for x in range(width):
for y in range(height):
r, g, b = pixels[x, y]
# Применение сепии
tr = int(0.393 * r + 0.769 * g + 0.189 * b)
tg = int(0.349 * r + 0.686 * g + 0.168 * b)
tb = int(0.272 * r + 0.534 * g + 0.131 * b)
pixels[x, y] = (min(255, tr), min(255, tg), min(255, tb))
Поддерживаемые форматы файлов
Основные форматы изображений
| Формат | Чтение | Запись | Анимация | Прозрачность | Сжатие |
|---|---|---|---|---|---|
| JPEG | ✓ | ✓ | ✗ | ✗ | Lossy |
| PNG | ✓ | ✓ | ✗ | ✓ | Lossless |
| GIF | ✓ | ✓ | ✓ | ✓ | Lossless |
| BMP | ✓ | ✓ | ✗ | ✗ | None/RLE |
| TIFF | ✓ | ✓ | ✓ | ✓ | Various |
| WebP | ✓ | ✓ | ✓ | ✓ | Both |
| ICO | ✓ | ✓ | ✗ | ✓ | Various |
| ✓ | ✓ | ✓ | ✗ | Various |
Специальные и RAW форматы
Pillow также поддерживает множество специализированных форматов:
- HEIF/HEIC — современный формат от Apple (требует дополнительных библиотек)
- AVIF — новый формат от Alliance for Open Media
- FLIF — экспериментальный lossless формат
- RAW форматы — через плагины (Canon CR2, Nikon NEF, и др.)
Практические примеры использования
Создание водяных знаков
def add_watermark(image_path, watermark_text, output_path):
img = Image.open(image_path).convert("RGBA")
# Создание прозрачного слоя для водяного знака
watermark = Image.new("RGBA", img.size, (255, 255, 255, 0))
draw = ImageDraw.Draw(watermark)
# Настройка шрифта
font_size = max(20, min(img.size) // 20)
font = ImageFont.load_default()
# Размещение текста по диагонали
bbox = draw.textbbox((0, 0), watermark_text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = img.width - text_width - 20
y = img.height - text_height - 20
draw.text((x, y), watermark_text, font=font, fill=(255, 255, 255, 128))
# Наложение водяного знака
watermarked = Image.alpha_composite(img, watermark)
watermarked.convert("RGB").save(output_path, "JPEG", quality=95)
# Использование
add_watermark("photo.jpg", "© Мой сайт", "watermarked_photo.jpg")
Генерация превью изображений
def create_thumbnail(input_path, output_path, size=(200, 200)):
with Image.open(input_path) as img:
# Создание превью с сохранением пропорций
img.thumbnail(size, Image.LANCZOS)
# Создание квадратного превью с заливкой
thumb = Image.new('RGB', size, (255, 255, 255))
offset = ((size[0] - img.size[0]) // 2, (size[1] - img.size[1]) // 2)
thumb.paste(img, offset)
thumb.save(output_path, "JPEG", quality=85)
Пакетная обработка изображений
import os
from pathlib import Path
def batch_process_images(input_folder, output_folder, max_size=(800, 600)):
input_path = Path(input_folder)
output_path = Path(output_folder)
output_path.mkdir(exist_ok=True)
supported_formats = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff'}
for file_path in input_path.iterdir():
if file_path.suffix.lower() in supported_formats:
try:
with Image.open(file_path) as img:
# Изменение размера с сохранением пропорций
img.thumbnail(max_size, Image.LANCZOS)
# Сохранение с оптимизацией
output_file = output_path / f"processed_{file_path.name}"
img.save(output_file, "JPEG", quality=85, optimize=True)
print(f"Обработан: {file_path.name}")
except Exception as e:
print(f"Ошибка при обработке {file_path.name}: {e}")
Интеграция с другими библиотеками
Работа с NumPy
import numpy as np
from PIL import Image
# Преобразование Pillow изображения в NumPy массив
img = Image.open("example.jpg")
img_array = np.array(img)
# Применение NumPy операций
# Увеличение яркости
bright_array = np.clip(img_array * 1.2, 0, 255).astype(np.uint8)
# Обратное преобразование в Pillow
bright_img = Image.fromarray(bright_array)
Интеграция с OpenCV
import cv2
from PIL import Image
import numpy as np
def pil_to_opencv(pil_img):
"""Преобразование Pillow изображения в формат OpenCV"""
return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
def opencv_to_pil(cv_img):
"""Преобразование OpenCV изображения в формат Pillow"""
return Image.fromarray(cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB))
Работа с Matplotlib
import matplotlib.pyplot as plt
from PIL import Image
# Отображение Pillow изображения в Matplotlib
img = Image.open("example.jpg")
plt.imshow(img)
plt.axis('off')
plt.title('Изображение из Pillow')
plt.show()
Полная таблица методов и функций библиотеки Pillow
Основные методы класса Image
| Метод | Описание | Пример использования |
|---|---|---|
Image.open(fp, mode='r') |
Открывает изображение из файла | img = Image.open("photo.jpg") |
Image.new(mode, size, color=0) |
Создает новое изображение | img = Image.new("RGB", (200, 200), "white") |
Image.frombytes(mode, size, data) |
Создает изображение из байтов | img = Image.frombytes("RGB", (10, 10), data) |
Image.fromarray(obj, mode=None) |
Создает изображение из массива | img = Image.fromarray(numpy_array) |
img.save(fp, format=None) |
Сохраняет изображение | img.save("output.png", "PNG") |
img.copy() |
Создает копию изображения | copy_img = img.copy() |
img.crop(box) |
Обрезает изображение | cropped = img.crop((0, 0, 100, 100)) |
img.paste(im, box=None) |
Вставляет изображение | img.paste(other_img, (10, 10)) |
img.resize(size, resample=None) |
Изменяет размер | resized = img.resize((300, 200)) |
img.rotate(angle, resample=0) |
Поворачивает изображение | rotated = img.rotate(45) |
img.transpose(method) |
Транспонирует изображение | flipped = img.transpose(Image.FLIP_LEFT_RIGHT) |
img.convert(mode=None) |
Конвертирует цветовой режим | gray = img.convert("L") |
img.filter(filter) |
Применяет фильтр | blurred = img.filter(ImageFilter.BLUR) |
img.point(lut, mode=None) |
Преобразует пиксели | enhanced = img.point(lambda x: x * 1.2) |
img.thumbnail(size, resample) |
Создает превью | img.thumbnail((128, 128)) |
Методы получения информации
| Метод/Атрибут | Описание | Возвращаемый тип |
|---|---|---|
img.format |
Формат файла | str или None |
img.mode |
Цветовой режим | str |
img.size |
Размер (ширина, высота) | tuple |
img.width |
Ширина изображения | int |
img.height |
Высота изображения | int |
img.info |
Метаданные изображения | dict |
img.getbands() |
Названия каналов | tuple |
img.getbbox() |
Ограничивающий прямоугольник | tuple или None |
img.getcolors(maxcolors) |
Список цветов в изображении | list |
img.getdata() |
Данные пикселей | ImagingCore |
img.getextrema() |
Минимальные и максимальные значения | tuple |
img.getpalette() |
Палитра изображения | list или None |
img.getpixel(xy) |
Значение пикселя | int или tuple |
img.histogram(mask=None) |
Гистограмма изображения | list |
Модуль ImageDraw
| Метод | Описание | Параметры |
|---|---|---|
ImageDraw.Draw(im, mode=None) |
Создает объект для рисования | im - изображение |
draw.arc(xy, start, end, fill=None) |
Рисует дугу | xy - координаты, углы в градусах |
draw.bitmap(xy, bitmap, fill=None) |
Рисует битмап | xy - позиция, bitmap - изображение |
draw.chord(xy, start, end, fill=None) |
Рисует хорду | xy - координаты эллипса |
draw.ellipse(xy, fill=None, outline=None) |
Рисует эллипс | xy - ограничивающий прямоугольник |
draw.line(xy, fill=None, width=0) |
Рисует линию | xy - координаты точек |
draw.pieslice(xy, start, end, fill=None) |
Рисует сектор | xy - координаты, углы |
draw.point(xy, fill=None) |
Рисует точки | xy - координаты |
draw.polygon(xy, fill=None, outline=None) |
Рисует многоугольник | xy - список координат |
draw.rectangle(xy, fill=None, outline=None) |
Рисует прямоугольник | xy - координаты углов |
draw.text(xy, text, fill=None, font=None) |
Рисует текст | xy - позиция, text - строка |
draw.textbbox(xy, text, font=None) |
Получает размеры текста | Возвращает (x1, y1, x2, y2) |
Модуль ImageFilter
| Фильтр | Описание | Параметры |
|---|---|---|
ImageFilter.BLUR |
Размытие | Нет параметров |
ImageFilter.CONTOUR |
Выделение контуров | Нет параметров |
ImageFilter.DETAIL |
Увеличение детализации | Нет параметров |
ImageFilter.EDGE_ENHANCE |
Усиление краев | Нет параметров |
ImageFilter.EDGE_ENHANCE_MORE |
Сильное усиление краев | Нет параметров |
ImageFilter.EMBOSS |
Тиснение | Нет параметров |
ImageFilter.FIND_EDGES |
Поиск границ | Нет параметров |
ImageFilter.SHARPEN |
Увеличение резкости | Нет параметров |
ImageFilter.SMOOTH |
Сглаживание | Нет параметров |
ImageFilter.SMOOTH_MORE |
Сильное сглаживание | Нет параметров |
ImageFilter.BoxBlur(radius) |
Прямоугольное размытие | radius - радиус |
ImageFilter.GaussianBlur(radius) |
Гауссово размытие | radius - радиус |
ImageFilter.UnsharpMask(radius, percent, threshold) |
Маска нерезкости | Настройки резкости |
ImageFilter.Kernel(size, kernel) |
Пользовательский фильтр | size - размер, kernel - матрица |
Модуль ImageEnhance
| Класс | Описание | Метод enhance() |
|---|---|---|
ImageEnhance.Brightness(image) |
Настройка яркости | factor > 1 = ярче, < 1 = темнее |
ImageEnhance.Color(image) |
Настройка насыщенности | factor > 1 = насыщеннее, 0 = ч/б |
ImageEnhance.Contrast(image) |
Настройка контрастности | factor > 1 = контрастнее |
ImageEnhance.Sharpness(image) |
Настройка резкости | factor > 1 = резче, 0 = размыто |
Модуль ImageFont
| Функция | Описание | Параметры |
|---|---|---|
ImageFont.load(filename) |
Загружает растровый шрифт | filename - путь к файлу |
ImageFont.load_default() |
Загружает шрифт по умолчанию | Нет параметров |
ImageFont.truetype(font, size) |
Загружает TrueType шрифт | font - путь, size - размер |
font.getsize(text) |
Получает размер текста | text - строка (устарело) |
font.getbbox(text) |
Получает ограничивающий прямоугольник | text - строка |
Модуль ImageOps
| Функция | Описание | Применение |
|---|---|---|
ImageOps.autocontrast(image) |
Автоматическая настройка контраста | Улучшение изображения |
ImageOps.colorize(image, black, white) |
Колоризация ч/б изображения | Стилизация |
ImageOps.crop(image, border) |
Обрезка с учетом рамки | border - размер рамки |
ImageOps.equalize(image) |
Выравнивание гистограммы | Улучшение контраста |
ImageOps.expand(image, border, fill) |
Расширение с рамкой | Добавление границ |
ImageOps.fit(image, size, method) |
Подгонка под размер | Изменение размера |
ImageOps.flip(image) |
Вертикальное отражение | Трансформация |
ImageOps.grayscale(image) |
Преобразование в оттенки серого | Цветовая коррекция |
ImageOps.invert(image) |
Инверсия цветов | Спецэффекты |
ImageOps.mirror(image) |
Горизонтальное отражение | Трансформация |
ImageOps.posterize(image, bits) |
Постеризация | bits - количество бит на канал |
ImageOps.solarize(image, threshold) |
Соляризация | threshold - порог |
Оптимизация производительности
Рекомендации по производительности
Для достижения максимальной производительности при работе с Pillow следует учитывать несколько важных аспектов:
Использование подходящих алгоритмов ресемплинга: При изменении размеров изображений выбор правильного алгоритма критически важен. Image.LANCZOS обеспечивает наилучшее качество, но работает медленнее. Для быстрой обработки можно использовать Image.BILINEAR или Image.NEAREST.
Работа с большими изображениями: При обработке изображений большого размера используйте метод thumbnail() вместо resize(), поскольку он оптимизирован для уменьшения размера и работает быстрее.
Пакетная обработка: При обработке множества изображений оптимизируйте процесс, избегая повторной загрузки шрифтов и создания объектов.
Управление памятью
# Правильное управление ресурсами
with Image.open("large_image.jpg") as img:
processed = img.resize((800, 600))
processed.save("output.jpg")
# Изображение автоматически закрывается
# Для очень больших изображений
import gc
for filename in large_image_list:
with Image.open(filename) as img:
process_image(img)
gc.collect() # Принудительная очистка памяти
Сравнение с другими библиотеками
Pillow vs OpenCV
| Аспект | Pillow | OpenCV |
|---|---|---|
| Основное назначение | Общая обработка изображений | Компьютерное зрение |
| Простота использования | Очень простая | Средняя сложность |
| Производительность | Хорошая для базовых операций | Высокая для сложных алгоритмов |
| Поддержка форматов | Широкая | Широкая |
| Работа с текстом | Отличная | Базовая |
| Машинное обучение | Нет | Встроенные алгоритмы |
| Размер библиотеки | Компактная | Большая |
| Документация | Отличная | Хорошая |
Pillow vs Wand (ImageMagick)
| Аспект | Pillow | Wand |
|---|---|---|
| Установка | Простая | Требует ImageMagick |
| Функциональность | Базовая-средняя | Очень широкая |
| Производительность | Хорошая | Высокая |
| API | Pythonic | Более сложный |
| Поддержка форматов | Хорошая | Превосходная |
| Эффекты | Базовые | Профессиональные |
Pillow vs Skimage
| Аспект | Pillow | Skimage |
|---|---|---|
| Назначение | Общая обработка | Научная обработка |
| Алгоритмы | Базовые | Научные |
| Интеграция с NumPy | Хорошая | Нативная |
| Простота | Очень простая | Средняя |
| Документация | Отличная | Академическая |
Часто задаваемые вопросы
Как установить Pillow на системе без административных прав?
Используйте виртуальное окружение Python или установку в пользовательскую директорию:
pip install --user pillow
# или
python -m venv myenv
source myenv/bin/activate # Linux/Mac
myenv\Scripts\activate # Windows
pip install pillow
Почему возникает ошибка "cannot identify image file"?
Эта ошибка обычно возникает по следующим причинам:
- Файл поврежден или имеет неподдерживаемый формат
- Файл не является изображением
- Отсутствуют необходимые кодеки
Решение:
try:
img = Image.open("file.jpg")
except IOError:
print("Невозможно открыть файл изображения")
Как работать с изображениями в памяти без сохранения на диск?
Используйте BytesIO для работы с изображениями в памяти:
from io import BytesIO
import requests
# Загрузка изображения из URL
response = requests.get("https://example.com/image.jpg")
img = Image.open(BytesIO(response.content))
# Сохранение в буфер
buffer = BytesIO()
img.save(buffer, format="PNG")
image_data = buffer.getvalue()
Как обработать EXIF данные изображения?
from PIL import Image
from PIL.ExifTags import TAGS
img = Image.open("photo.jpg")
exifdata = img.getexif()
for tag_id in exifdata:
tag = TAGS.get(tag_id, tag_id)
data = exifdata.get(tag_id)
print(f"{tag}: {data}")
Почему изображения после обработки стали больше по размеру файла?
Это может происходить по нескольким причинам:
- Изменение формата сжатия
- Увеличение качества сохранения
- Добавление метаданных
Для оптимизации размера:
img.save("output.jpg", "JPEG", quality=85, optimize=True)
Как создать прозрачный фон у изображения?
# Создание изображения с прозрачным фоном
img = Image.new("RGBA", (200, 200), (0, 0, 0, 0))
# Преобразование существующего изображения
img = img.convert("RGBA")
data = img.getdata()
newData = []
for item in data:
if item[0] == 255 and item[1] == 255 and item[2] == 255: # белый цвет
newData.append((255, 255, 255, 0)) # делаем прозрачным
else:
newData.append(item)
img.putdata(newData)
Как обрезать изображение по содержимому (автоматическая обрезка)?
# Автоматическая обрезка пустых областей
bbox = img.getbbox()
if bbox:
img = img.crop(bbox)
Как добавить тень к тексту?
from PIL import Image, ImageDraw, ImageFont, ImageFilter
img = Image.new("RGB", (400, 200), "white")
draw = ImageDraw.Draw(img)
font = ImageFont.load_default()
# Создание тени
shadow = Image.new("RGBA", img.size, (0, 0, 0, 0))
shadow_draw = ImageDraw.Draw(shadow)
shadow_draw.text((52, 52), "Текст с тенью", font=font, fill=(0, 0, 0, 128))
shadow = shadow.filter(ImageFilter.GaussianBlur(2))
# Наложение тени и текста
img.paste(shadow, (0, 0), shadow)
draw.text((50, 50), "Текст с тенью", font=font, fill="black")
Заключение
Библиотека Pillow представляет собой мощный и универсальный инструмент для работы с изображениями в Python. Её простота использования, обширная функциональность и активная поддержка сообщества делают её незаменимой для широкого спектра задач — от базовой обработки фотографий до создания сложных графических приложений.
Основные преимущества Pillow включают интуитивно понятный API, отличную документацию, широкую поддержку форматов файлов и эффективную интеграцию с экосистемой Python. Библиотека постоянно развивается, регулярно получает обновления безопасности и новые возможности.
Для начинающих разработчиков Pillow предоставляет простой путь входа в мир обработки изображений, в то время как опытные программисты найдут в ней достаточно возможностей для решения сложных задач. Комбинация с другими библиотеками, такими как NumPy, OpenCV или Matplotlib, открывает еще более широкие возможности для работы с графическими данными.
Независимо от того, создаете ли вы веб-приложение с динамической генерацией изображений, разрабатываете систему компьютерного зрения или просто хотите автоматизировать обработку фотографий, Pillow предоставляет необходимые инструменты для достижения ваших целей.
Настоящее и будущее развития ИИ: классической математики уже недостаточно
Эксперты предупредили о рисках фейковой благотворительности с помощью ИИ
В России разработали универсального ИИ-агента для роботов и индустриальных процессов