Изменение размера изображения в Python без потери данных EXIF - PullRequest
25 голосов
/ 30 декабря 2008

Мне нужно изменить размер изображений jpg с помощью Python без потери данных EXIF ​​исходного изображения (метаданные о дате съемки, модели камеры и т. Д.). Все поиски в Google по поводу python и изображений указывают на библиотеку PIL, которую я сейчас использую, но, похоже, не в состоянии сохранить метаданные. Код, который у меня есть (с использованием PIL), таков:

img = Image.open('foo.jpg')
width,height = 800,600
if img.size[0] < img.size[1]:
    width,height = height,width

resized_img = img.resize((width, height), Image.ANTIALIAS) # best down-sizing filter
resized_img.save('foo-resized.jpg')

Есть идеи? Или другие библиотеки, которые я мог бы использовать?

Ответы [ 10 ]

10 голосов
/ 24 ноября 2010

Вы можете использовать pyexiv2 для копирования данных EXIF ​​из исходного изображения. В следующем примере размер изображения изменяется с использованием библиотеки PIL, данные EXIF, скопированные с помощью pyexiv2, и поля EXIF ​​размера изображения устанавливаются с новым размером.

def resize_image(source_path, dest_path, size):
    # resize image
    image = Image.open(source_path)
    image.thumbnail(size, Image.ANTIALIAS)
    image.save(dest_path, "JPEG")

    # copy EXIF data
    source_image = pyexiv2.Image(source_path)
    source_image.readMetadata()
    dest_image = pyexiv2.Image(dest_path)
    dest_image.readMetadata()
    source_image.copyMetadataTo(dest_image)

    # set EXIF image size info to resized size
    dest_image["Exif.Photo.PixelXDimension"] = image.size[0]
    dest_image["Exif.Photo.PixelYDimension"] = image.size[1]
    dest_image.writeMetadata()

# resizing local file
resize_image("41965749.jpg", "resized.jpg", (600,400))
10 голосов
/ 30 декабря 2008
import jpeg
jpeg.setExif(jpeg.getExif('foo.jpg'), 'foo-resized.jpg') 

http://www.emilas.com/jpeg/

7 голосов
/ 27 февраля 2014

На самом деле существует действительно простой способ копирования EXIF-данных из одного изображения в другое с использованием только PIL. Хотя это не позволяет изменять теги exif.

image = Image.open('test.jpg')
exif = image.info['exif']
# Your picture process here
image = image.rotate(90)
image.save('test_rotated.jpg', 'JPEG', exif=exif)

Как видите, функция сохранения может принимать аргумент exif, который позволяет копировать необработанные данные exif в новое изображение при сохранении. На самом деле вам не нужна никакая другая библиотека, если это все, что вы хотите сделать. Кажется, я не могу найти какую-либо документацию по параметрам сохранения, и я даже не знаю, относится ли она к Pillow или к работе с PIL. (Если у кого-то есть какая-то ссылка, я был бы рад, если бы он разместил ее в комментариях)

4 голосов
/ 30 декабря 2008

Почему бы не использовать ImageMagick ?
Это довольно стандартный инструмент (например, это стандартный инструмент, используемый в Gallery 2); Я никогда не использовал его, однако он также имеет интерфейс Python (или, вы также можете просто вызывать команду) и, прежде всего, должен поддерживать EXIF-информацию между всеми преобразованиями.

2 голосов
/ 09 июля 2013

Для pyexiv2 v0.3.2 документация API относится к методу копирования для переноса данных EXIF ​​из одного изображения в другое. В этом случае это будут EXIF-данные исходного изображения с измененным размером.

Выходит @ Максим Козленко, обновленный код для копирования данных EXIF:

    source_image = pyexiv2.ImageMetadata(source_path)
    source_image.read()

    dest_image = pyexiv2.ImageMetadata(dest_path)
    dest_image.read()

    source_image.copy(dest_image,exif=True)
    dest_image.write()
1 голос
/ 09 августа 2018

Вот обновленный ответ по состоянию на 2018. piexif - это чистая библиотека python, которая для меня легко устанавливается через pip (pip install piexif) и прекрасно работает (спасибо, сопровождающие!). https://pypi.org/project/piexif/

Использование очень просто, одна строка будет копировать принятый ответ и скопировать все EXIF-теги из исходного изображения в изображение с измененным размером:

import piexif
piexif.transplant("foo.jpg", "foo-resized.jpg")

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

1 голос
/ 31 декабря 2008

Вы можете использовать pyexiv2 для изменения файла после его сохранения.

0 голосов
/ 14 мая 2015

Кажется, решение @ Depado не работает для меня, в моем сценарии изображение даже не содержит сегмент exif.

pyexiv2 трудно установить на моем Mac, вместо этого я использую модуль pexif https://github.com/bennoleslie/pexif/blob/master/pexif.py. Чтобы «добавить сегмент exif» к изображению не содержит информацию exif, я добавил информацию exif, содержащуюся в изображении, которому принадлежит сегмент EXIF ​​

from pexif import JpegFile

#get exif segment from an image
jpeg = JpegFile.fromFile(path_with_exif)
jpeg_exif = jpeg.get_exif()

#import the exif segment above to the image file which does not contain exif segment
jpeg = JpegFile.fromFile(path_without_exif)
exif = jpeg.import_exif(jpeg_exif)
jpeg.writeFile(path_without_exif)
0 голосов
/ 04 сентября 2014
from PIL import Image
img_path = "/tmp/img.jpg"
img = Image.open(img_path)
exif = img.info['exif']
img.save("output_"+img_path, exif=exif)

Проверено в подушке 2.5.3

0 голосов
/ 30 декабря 2008

PIL обрабатывает данные EXIF, не так ли? Посмотрите в PIL.ExifTags.

...