Подтвердить что ты не робот

Изменение размера изображения на Python без потери данных EXIF

Мне нужно изменить размер 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')

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

4b9b3361

Ответ 2

Вы можете использовать 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))

Ответ 3

На самом деле существует действительно простой способ копирования данных 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 в новом изображении при сохранении. На самом деле вам не нужен какой-либо другой lib, если это все, что вы хотите сделать. Я не могу найти какую-либо документацию по параметрам сохранения, и я даже не знаю, относится ли это к подушке или работает с PIL. (Если у кого-то есть какая-то ссылка, мне понравилось бы, если бы они разместили ее в комментариях)

Ответ 4

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

Ответ 5

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

Ответ 6

Для 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()

Ответ 7

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

Ответ 8

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

Ответ 9

Кажется, решение @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)