Pregunta

Necesito cambiar el tamaño de las imágenes jpg con Python sin perder los datos EXIF ??de la imagen original (metadatos sobre la fecha de captura, modelo de cámara, etc.). Todas las búsquedas de Google sobre python e imágenes apuntan a la biblioteca PIL que estoy usando actualmente, pero no parece poder conservar los metadatos. El código que tengo hasta ahora (usando PIL) es este:

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')

¿Alguna idea? ¿O otras bibliotecas que podría estar usando?

¿Fue útil?

Solución

import jpeg
jpeg.setExif(jpeg.getExif('foo.jpg'), 'foo-resized.jpg') 

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

Otros consejos

Puede usar pyexiv2 para copiar datos EXIF ??de la imagen de origen. En el siguiente ejemplo, la imagen se redimensiona utilizando la biblioteca PIL, los datos EXIF ??copiados con pyexiv2 y los campos EXIF ??de tamaño de imagen se configuran con un nuevo tamaño.

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))

En realidad, existe una forma realmente sencilla de copiar datos EXIF ??de una imagen a otra con solo PIL. Aunque no permite modificar las etiquetas 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)

Como puede ver, la función de guardar puede tomar el argumento exif que permite copiar los datos exif sin formato en la nueva imagen al guardar. En realidad, no necesitas ninguna otra biblioteca si eso es todo lo que quieres hacer. Parece que no puedo encontrar ninguna documentación sobre las opciones de guardar y ni siquiera sé si eso es específico de Pillow o si también estoy trabajando con PIL. (Si alguien tiene algún tipo de enlace, me gustaría que lo publicaran en los comentarios)

¿Por qué no usar ImageMagick ?
Es una herramienta bastante estándar (por ejemplo, es la herramienta estándar utilizada por la Galería 2); Nunca lo he usado, sin embargo, también tiene una interfaz de python (o, puedes también simplemente genera el comando) y, sobre todo, debe mantener la información EXIF ??entre todas las transformaciones.

Para pyexiv2 v0.3.2, documentación de la API se refiere al método de copia para transferir datos EXIF ??de una imagen a otra. En este caso, serían los datos EXIF ??de la imagen original sobre la imagen redimensionada.

Saliendo de @Maksym Kozlenko, el código actualizado para copiar datos EXIF ??es:

    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()

Puede usar pyexiv2 para modificar el archivo después de guardarlo.

Aquí hay una respuesta actualizada a partir de 2018. piexif es una biblioteca Python pura que, para mí, se instaló fácilmente a través de pip (pip install piexif) y funcionó a la perfección (¡gracias, mantenedores!). https://pypi.org/project/piexif/

El uso es muy simple, una sola línea replicará la respuesta aceptada y copiará todas las etiquetas EXIF ??de la imagen original a la imagen redimensionada:

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

No lo he intentado todavía, pero parece que también podría realizar modificaciones fácilmente usando las funciones de carga, volcado e inserción como se describe en la documentación vinculada.

PIL maneja datos EXIF, ¿no es así? Busque en PIL.ExifTags.

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)

Probado en almohada 2.5.3

Parece que la solución de @ Depado no me funciona, en mi caso, la imagen ni siquiera contiene un segmento exif.

pyexiv2 es difícil de instalar en mi Mac, en vez de eso, uso el módulo pexif https : //github.com/bennoleslie/pexif/blob/master/pexif.py . Para " agregar segmento exif " a una imagen no contiene información exif, agregué la información exif contenida en una imagen que posee un segmento 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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top