Библиотека Pillow для обработки изображений в Python
Основы работы с библиотекой Pillow
Библиотека Pillow (форк PIL) предоставляет инструменты для открытия, изменения и сохранения растровых изображений в Python. Она поддерживает множество форматов (PNG, JPEG, BMP, GIF, TIFF) и предлагает функции для фильтрации, трансформации, рисования и анализа изображений.
Как открыть, изменить размер, применить фильтр и сохранить изображение?
Наиболее универсальный способ обработки изображения включает базовую последовательность: загрузка, трансформация, фильтрация и сохранение. Этот подход подходит для большинства задач – от уменьшения фото до пакетной обработки.
from PIL import Image, ImageFilter
# Открыть изображение
img = Image.open('photo.jpg')
# Изменить размер (ширина 300, высота пропорционально)
new_size = (300, int(img.height * 300 / img.width))
img_resized = img.resize(new_size)
# Применить размытие
img_blurred = img_resized.filter(ImageFilter.BLUR)
# Сохранить в новом формате
img_blurred.save('photo_blurred.png')
Python работа с изображениями библиотеки (работа с изображениями в python с помощью библиотек)
На выходе получается файл photo_blurred.png размером 300×... с размытым эффектом.
Python pillow image (библиотека pillow для изображений)
Типичные ошибки:
- Файл не найден – указывайте полный путь или проверьте текущую директорию.
- Ошибка формата – Pillow не поддерживает некоторые редкие форматы; конвертируйте через Image.open с указанием формата.
- Пропорции искажаются – если в resize задать абсолютные значения без учёта соотношения сторон, изображение сожмётся. Используйте thumbnail для сохранения пропорций.
Как обрезать изображение по координатам?
Обрезка (crop) полезна для выделения фрагмента, удаления лишних полей или создания аватарок.
from PIL import Image
img = Image.open('photo.jpg')
# Координаты: лево, верх, право, низ
cropped = img.crop((100, 50, 400, 300))
cropped.save('cropped.jpg')
Python размер изображения (получение размеров изображения в python)
Проблема: выход за границы изображения
Если координаты выходят за пределы, Pillow вызовет ошибку. Проверяйте размеры через img.size.
Как повернуть изображение на произвольный угол?
Поворот (rotate) используется для коррекции наклона, создания эффектов или анимации.
from PIL import Image
img = Image.open('photo.jpg')
# Поворот на 45 градусов, с расширением холста (expand=True)
rotated = img.rotate(45, expand=True, fillcolor='white')
rotated.save('rotated.jpg')
Python сохранить изображение (сохранение изображения с помощью python)
Изображение поворачивается, незаполненные области заливаются белым.
Проблема: пикселизация при повороте
При больших углах края могут стать ступенчатыми. Используйте Image.Resampling.LANCZOS для высокого качества (параметр resample).
Как наложить текст на изображение?
Наложение текста востребовано для водяных знаков, подписей, создания мемов.
from PIL import Image, ImageDraw, ImageFont
img = Image.open('photo.jpg')
draw = ImageDraw.Draw(img)
font = ImageFont.truetype('arial.ttf', 40) # путь к шрифту
draw.text((50, 50), "Пример текста", fill='red', font=font)
img.save('text.jpg')
Ошибка: шрифт не найден
Укажите полный путь к файлу шрифта (.ttf) или используйте стандартный ImageFont.load_default().
Как работать с прозрачностью (альфа-канал)?
PNG поддерживает прозрачность. Добавление или изменение альфа-канала применяется при создании логотипов, наложении слоёв.
from PIL import Image
img = Image.open('logo.png').convert('RGBA')
data = img.getdata()
# Увеличить прозрачность (уменьшить альфа)
new_data = []
for pixel in data:
r, g, b, a = pixel
new_data.append((r, g, b, a // 2)) # полупрозрачность
img.putdata(new_data)
img.save('logo_half_transparent.png')
Проблема: изображение без альфа-канала
Перед работой конвертируйте в режим 'RGBA' или 'LA' (если нужно полутоновое с альфа).
Как создать изображение с нуля (пустое или с градиентом)?
Генерация изображений полезна для тестов, графиков, фонов.
from PIL import Image
# Пустое белое изображение 500x300
img = Image.new('RGB', (500, 300), color='white')
# Или с градиентом (попиксельно – медленно)
for x in range(500):
for y in range(300):
r = int(255 * x / 500)
g = int(255 * y / 300)
b = 128
img.putpixel((x, y), (r, g, b))
img.save('gradient.png')
Проблема: медленная генерация
Циклы по пикселям неэффективны. Используйте ImageDraw или массивы NumPy с последующим преобразованием.
Как конвертировать изображение из одного формата в другой?
Простое изменение расширения файла не меняет формат. Pillow конвертирует при сохранении.
from PIL import Image
img = Image.open('photo.bmp')
img.save('photo.jpg', quality=85) # JPEG с качеством 85%
img.save('photo.png') # PNG без потерь
Ошибка: неподдерживаемый режим для формата
Например, JPEG не поддерживает прозрачность. Конвертируйте в RGB перед сохранением.
Как получить гистограмму изображения?
Гистограмма показывает распределение интенсивности пикселей, полезна для анализа яркости, контрастности.
from PIL import Image
img = Image.open('photo.jpg').convert('L') # в оттенки серого
hist = img.histogram()
# hist – список из 256 значений (0..255)
print(hist[100:110]) # пример значений
Расширенные примеры работы с библиотекой Pillow
В этом разделе представлены более сложные сценарии: пакетная обработка, создание коллажей, работа с анимацией, пользовательские фильтры и извлечение метаданных.
Как создать коллаж из нескольких изображений?
Коллаж объединяет несколько фото в одно полотно. Пример: сетка 2×2.
from PIL import Image
# Загружаем изображения
imgs = [Image.open(f'img{i}.jpg') for i in range(1,5)]
# Приводим к одинаковому размеру (200x200)
imgs_resized = [img.resize((200,200)) for img in imgs]
# Создаём пустое полотно 400x400
canvas = Image.new('RGB', (400,400), 'white')
# Размещаем: (0,0), (200,0), (0,200), (200,200)
canvas.paste(imgs_resized[0], (0,0))
canvas.paste(imgs_resized[1], (200,0))
canvas.paste(imgs_resized[2], (0,200))
canvas.paste(imgs_resized[3], (200,200))
canvas.save('collage.jpg')
Файл collage.jpg содержит сетку из четырёх изображений.
Как обработать папку с изображениями (batch)?
Пакетная обработка применяется для однотипных действий (изменение размера, добавление водяного знака).
import os
from PIL import Image
input_dir = 'photos'
output_dir = 'resized'
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if filename.lower().endswith(('.jpg','.png','.bmp')):
img = Image.open(os.path.join(input_dir, filename))
img.thumbnail((800,800)) # сохраняя пропорции
img.save(os.path.join(output_dir, filename))
print(f"Обработан {filename}")
Все изображения из папки photos будут уменьшены до 800×800 (максимальная сторона) и сохранены в resized.
Как применить пользовательский фильтр (свёртку)?
Свёртка позволяет создавать эффекты размытия, резкости, тиснения, используя матрицу ядра.
from PIL import Image, ImageFilter
img = Image.open('photo.jpg')
# Ядро для усиления резкости
kernel = [-1, -1, -1,
-1, 9, -1,
-1, -1, -1]
sharpened = img.filter(ImageFilter.Kernel((3,3), kernel, scale=1, offset=0))
sharpened.save('sharpened.jpg')
Изображение становится более чётким, края контрастнее.
Как извлечь метаданные (EXIF) из фотографии?
EXIF содержит информацию о камере, дате, GPS. Pillow предоставляет доступ к EXIF.
from PIL import Image
img = Image.open('photo.jpg')
exif_data = img._getexif()
if exif_data:
for tag, value in exif_data.items():
print(f"{tag}: {value}")
else:
print("Нет EXIF данных")
Выводится словарь с числовыми тегами. Для человекочитаемых названий используйте pillow_heif или ExifRead.
Как создать анимированный GIF из кадров?
Pillow поддерживает многослойные GIF. Пример: анимация из трёх статических изображений.
from PIL import Image
frames = [Image.open(f'frame{i}.png') for i in range(3)]
# Первый кадр – основа, остальные добавляем
frames[0].save('animation.gif', save_all=True, append_images=frames[1:], duration=500, loop=0)
Создаётся GIF-анимация с бесконечным циклом, каждый кадр показывается 500 мс.
Проблема: разные размеры кадров
Pillow не может объединить кадры разного размера – приведите их к единому размеру до сохранения.
Как использовать маску для выборочного применения эффекта?
Маска (изображение в градациях серого) определяет, где эффект применяется сильнее (белые участки) или слабее (чёрные).
from PIL import Image, ImageFilter
img = Image.open('photo.jpg')
mask = Image.open('mask.png').convert('L') # чёрно-белая маска
# Применяем размытие ко всему изображению
blurred = img.filter(ImageFilter.GaussianBlur(radius=5))
# Комбинируем с помощью composite
result = Image.composite(blurred, img, mask)
result.save('masked_blur.jpg')
Области, где на маске белый цвет, становятся размытыми; чёрные – остаются исходными.
Как конвертировать изображение в режим палитры (цветовую таблицу)?
Палитровые изображения (P mode) занимают меньше места и могут быть использованы для ретро-эффектов.
from PIL import Image
img = Image.open('photo.jpg')
# Конвертация в палитру с 16 цветами (адаптивная)
img_p = img.quantize(colors=16, method=Image.MEDIANCUT)
img_p.save('palette_16.png')
Изображение уменьшает количество цветов, создавая эффект плаката.
Как выполнить пакетную обработку с использованием многопоточности?
Для ускорения обработки большого количества файлов.
import os
from concurrent.futures import ThreadPoolExecutor
from PIL import Image
def process(file):
img = Image.open(file)
img.thumbnail((400,400))
img.save('out/' + os.path.basename(file))
files = [f for f in os.listdir('photos') if f.lower().endswith(('.jpg','.png'))]
with ThreadPoolExecutor(max_workers=4) as executor:
executor.map(process, ['photos/'+f for f in files])
Параллельно обрабатываются до 4 файлов одновременно, что сокращает общее время при работе ввода-вывода.