Сообщить об ошибке.

Функция Image.open() модуля Pillow в Python

Способы открыть изображение для редактирования в Python

Содержание:

Синтаксис и описание функции Image.open():

from PIL import Image

img = Image.open(fp, mode='r', formats=None)

Параметры:

  • fp - имя файла (строка), pathlib.Path объект или объект file. Объект file должен иметь методы file.read, file.seek и file.tell методы и открыт в двоичном режиме.
  • mode='r' - режим. Если задан, то должен быть r.
  • formats=None - список или кортеж форматов, в которых нужно попытаться загрузить файл. Аргумент можно использовать для ограничения набора проверяемых форматов. Значение None означает все поддерживаемые форматы. Можно распечатать набор доступных форматов, запустив python3 -m PIL или используя функцию PIL.features.pilinfo().

Возвращаемое значение:

  • Объект изображения Image.

Описание:

Функция Image.open() модуля Pillow открывает и идентифицирует данный файл изображения.

Это ленивая операция. Функция Image.open() идентифицирует файл, файл остается открытым, а фактические данные изображения не считываются до тех пор, пока не будет предпринята попытка обработать данные (или не будет вызван метод img.load().

Пользователи библиотеки должны использовать диспетчер контекста или вызывать img.close() для любого изображения, открытого с помощью имени файла или объекта pathlib.Path для закрытия базового файла.

Способы открытия файла:

from PIL import Image
import io
import pathlib

with Image.open("test.jpg") as img:
    ...

with Image.open(pathlib.Path("test.jpg")) as img2:
    ...

with open("test.jpg", "rb") as f:
    img3 = Image.open(f)
    ...

with open("test.jpg", "rb") as f:
    img4 = Image.open(io.BytesIO(f.read()))
    ...

Если имя файла или объект pathlib.Path передается Pillow, то результирующий файловый объект, открытый Pillow, также может быть закрыт Pillow после вызова метода img.load(), при условии, что связанное изображение не имеет нескольких кадров.

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

Возможные исключения при открытии файла изображения:

  • FileNotFoundError: если файл не найден.
  • PIL.UnidentifiedImageError: если изображение не может быть идентифицировано и открыто.
  • ValueError: если аргумент моде не r или если для файлового потока fp используется экземпляр StringIO.
  • TypeError: если аргумент formats не содержит открываемого формата изображения.

Жизненный цикл изображения.

  1. Имена файлов и объекты pathlib.Path открываются Image.open() как файл. Из открытого файла считываются метаданные. Файл остается открытым для дальнейшего использования.
  2. Когда требуются пиксельные данные изображения, вызывается метод img.load(). Текущий кадр считывается в память. Изображение теперь можно использовать независимо от базового файла изображения.
  3. Любой метод Pillow, который создает новый экземпляр изображения на основе другого, будет внутренне вызывать img.load() для исходного изображения, а затем считывать данные. Новый экземпляр изображения не будет связан с исходным файлом изображения.
  4. Если имя файла или объект pathlib.Path были переданы Image.open(), то файловый объект был открыт Pillow и считается, что он используется исключительно Pillow. Таким образом, если изображение представляет собой однокадровое изображение, файл будет закрыт в этом методе после того, как кадр будет прочитан. Если изображение представляет собой многокадровое изображение (например, многостраничный TIFF и анимированный GIF), файл изображения остается открытым, чтобы img.seek() мог загрузить соответствующий кадр.
  5. Метод img.close() закрывает файл и уничтожает основной объект изображения. Менеджер контекста Pillow также закроет файл, но не уничтожит основной объект изображения.

Например:

with Image.open("test.jpg") as img:
    img.load()
assert img.fp is None
img.save("test.png")

Жизненный цикл однокадрового изображения относительно прост. Файл должен оставаться открытым до тех пор, пока не будет вызвана функция img.load() или img.close() или не завершится контекстный менеджер.

Многокадровые изображения более сложны. Метод img.load() не является терминальным методом, поэтому он не должен закрывать базовый файл. Как правило, Pillow не знает, будут ли какие-либо запросы на дополнительные данные, пока вызывающая сторона явно не закроет изображение.

Примеры использования функции Image.open().

Открыть, повернуть и отобразить изображение (используя средство просмотра по умолчанию):

from PIL import Image

with Image.open("test.jpg") as img:
    img.rotate(45).show()

Идентификация файлов изображений.

import sys
from PIL import Image

for infile in sys.argv[1:]:
    try:
        with Image.open(infile) as img:
            print(infile, img.format, f"{img.size}x{img.mode}")
    except OSError:
        pass

Открыть изображение по URL.

from PIL import Image
from urllib.request import urlopen

url = "https://python-pillow.org/images/pillow-logo.png"
with Image.open(urlopen(url)) as img:
    img.save('pillow-logo.png')

Чтение изображений из архива tar.

from PIL import Image, TarIO

with TarIO.TarIO("test.tar", "hopper.jpg") as fp:
    img = Image.open(fp)

Чтение изображения в режиме черновика.

Доступно только для файлов JPEG и MPO.

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

Метод img.draft() манипулирует открытым, но еще не загруженным изображением, чтобы оно максимально соответствовало заданному режиму и размеру. Это делается путем перенастройки декодера изображений.

from PIL import Image

with Image.open(file) as img:
    print("original =", img.mode, img.size)

    img.draft("L", (100, 100))
    print("draft =", img.mode, img.size)

Создание миниатюр.

Следующий код создает красивые эскизы всех изображений JPEG в текущем каталоге, сохраняя соотношение сторон с максимальным разрешением 128x128.

from PIL import Image
import glob, os

size = 128, 128

for infile in glob.glob("*.jpg"):
    file, ext = os.path.splitext(infile)
    with Image.open(infile) as img:
        img.thumbnail(size)
        img.save(f"{file}.thumbnail", "JPEG")