Domanda

Devo ridimensionare le immagini jpg con Python senza perdere i dati EXIF ??dell'immagine originale (metadati sulla data di acquisizione, modello della fotocamera, ecc.). Tutte le ricerche su Google su Python e le immagini rimandano alla libreria PIL che sto attualmente utilizzando, ma non sembra essere in grado di conservare i metadati. Il codice che ho finora (usando PIL) è questo:

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

Qualche idea? O altre librerie che potrei usare?

È stato utile?

Soluzione

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

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

Altri suggerimenti

È possibile utilizzare pyexiv2 per copiare i dati EXIF ??dall'immagine di origine. Nell'esempio seguente l'immagine viene ridimensionata utilizzando la libreria PIL, i dati EXIF ??copiati con pyexiv2 e le dimensioni dei campi EXIF ??delle dimensioni dell'immagine vengono impostati con nuove dimensioni.

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

In realtà esiste un modo davvero semplice di copiare i dati EXIF ??da un'immagine a un'altra con solo PIL. Anche se non consente di modificare i tag 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)

Come puoi vedere, la funzione di salvataggio può prendere l'argomento exif che consente di copiare i dati exif grezzi nella nuova immagine durante il salvataggio. In realtà non hai bisogno di altre lib se questo è tutto ciò che vuoi fare. Non riesco a trovare alcuna documentazione sulle opzioni di salvataggio e non so nemmeno se sia specifico per Pillow o per lavorare con PIL. (Se qualcuno ha qualche tipo di link, mi piacerebbe se lo pubblicassero nei commenti)

Perché non usare ImageMagick ?
È piuttosto uno strumento standard (ad esempio, è lo strumento standard utilizzato dalla Galleria 2); Non l'ho mai usato, tuttavia ha anche una interfaccia python (oppure, puoi genera semplicemente il comando) e, soprattutto, dovrebbe conservare le informazioni EXIF ??tra tutte le trasformazioni.

Per pyexiv2 v0.3.2, la Documentazione API si riferisce al metodo di copia per trasferire i dati EXIF ??da un'immagine all'altra. In questo caso sarebbero i dati EXIF ??dell'immagine originale sull'immagine ridimensionata.

Uscendo da @Maksym Kozlenko, il codice aggiornato per la copia dei dati 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()

Puoi usare pyexiv2 per modificare il file dopo averlo salvato.

Ecco una risposta aggiornata a partire dal 2018. piexif è una libreria in puro pitone che per me è stata installata facilmente tramite pip (pip install piexif) e ha funzionato magnificamente (grazie, manutentori!). https://pypi.org/project/piexif/

L'uso è molto semplice, una sola riga replicherà la risposta accettata e copierà tutti i tag EXIF ??dall'immagine originale all'immagine ridimensionata:

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

Non ho ancora provato, ma sembra che tu possa anche eseguire facilmente le modifiche usando le funzioni load, dump e insert come descritto nella documentazione collegata.

PIL gestisce i dati EXIF, vero? Cerca in 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)

Testato in Pillow 2.5.3

Sembra che la soluzione di @ Depado non funzioni per me, nel mio scenario l'immagine non contiene nemmeno un segmento exif.

pyexiv2 è difficile da installare sul mio Mac, invece utilizzo il modulo pexif https : //github.com/bennoleslie/pexif/blob/master/pexif.py . Per "aggiungere il segmento exif" a un'immagine non contiene informazioni exif, ho aggiunto le informazioni exif contenute in un'immagine che possiede 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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top