Question

Je dois redimensionner les images jpg avec Python sans perdre les données EXIF ??de l'image d'origine (métadonnées sur la date prise, modèle d'appareil photo, etc.). Toutes les recherches Google sur python et les images pointent vers la bibliothèque PIL que j'utilise actuellement, mais ne semblent pas pouvoir conserver les métadonnées. Le code que j’ai jusqu’à présent (en utilisant PIL) est le suivant:

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

Des idées? Ou d'autres bibliothèques que je pourrais utiliser?

Était-ce utile?

La solution

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

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

Autres conseils

Vous pouvez utiliser pyexiv2 pour copier des données EXIF ??à partir de l'image source. Dans l'exemple suivant, l'image est redimensionnée à l'aide de la bibliothèque PIL, les données EXIF ??copiées avec pyexiv2 et les champs EXIF ??de taille d'image sont définis avec une nouvelle taille.

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

Il existe en fait un moyen très simple de copier des données EXIF ??d’une photo à une autre avec uniquement de la liste d’information personnelle. Bien que cela ne permette pas de modifier les tags 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)

Comme vous pouvez le constater, la fonction de sauvegarde peut prendre l’argument exif qui permet de copier les données exif brutes dans la nouvelle image lors de la sauvegarde. Vous n'avez en fait besoin d'aucune autre bibliothèque si c'est tout ce que vous voulez faire. Je n'arrive pas à trouver de documentation sur les options de sauvegarde et je ne sais même pas si cela concerne spécifiquement Pillow ou si vous travaillez avec PIL. (Si quelqu'un a un type de lien, je l'apprécierais s'il l'a posté dans les commentaires.)

Pourquoi ne pas utiliser ImageMagick ?

C'est un outil assez standard (par exemple, c'est l'outil standard utilisé par Gallery 2); Je ne l'ai jamais utilisé, mais il possède également une interface python (ou Il suffit également de lancer la commande) et surtout de conserver les informations EXIF ??entre toutes les transformations.

Pour pyexiv2 v0.3.2, le documentation sur l'API fait référence à la méthode de copie permettant de transférer des données EXIF ??d'une image à une autre. Dans ce cas, il s'agirait des données EXIF ??de l'image d'origine et de l'image redimensionnée.

En quittant @Maksym Kozlenko, le code mis à jour pour copier les données EXIF ??est le suivant:

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

Vous pouvez utiliser pyexiv2 pour modifier le fichier après l'avoir enregistré.

Voici une réponse mise à jour à partir de 2018. piexif est une bibliothèque python pure qui, pour moi, s’installe facilement via pip (pip install piexif) et fonctionne à merveille (merci, mainteneurs!). https://pypi.org/project/piexif/

L'utilisation est très simple: une seule ligne réplique la réponse acceptée et copie toutes les balises EXIF ??de l'image d'origine vers l'image redimensionnée:

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

Je n'ai pas encore essayé, mais il semble que vous puissiez également effectuer facilement des modifications en utilisant les fonctions de chargement, de vidage et d'insertion décrites dans la documentation liée.

PIL gère les données EXIF, n'est-ce pas? Regardez dans 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)

Testé dans l'oreiller 2.5.3

Il semble que la solution de @ Depado ne fonctionne pas pour moi. Dans mon scénario, l'image ne contient même pas de segment exif.

pyexiv2 est difficile à installer sur mon Mac, j'utilise plutôt le module pexif https : //github.com/bennoleslie/pexif/blob/master/pexif.py . Pour " ajouter un segment exif " à une image ne contenant pas d’informations exif, j’ai ajouté les informations exif contenues dans une image possédant un segment 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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top