Para evitar iniciar un nuevo proceso para cada imagen, debe comenzar exiftool
usando la bandera -stay_open
. A continuación, puede enviar comandos al proceso mediante stdin y leer la salida en stdout. ExifTool admite salida JSON, que es probablemente la mejor opción para leer los metadatos.
Aquí hay una clase simple que inicia un proceso exiftool
y presenta un método execute()
para enviar comandos a ese proceso. También incluí get_metadata()
para leer los metadatos en formato JSON:
import subprocess
import os
import json
class ExifTool(object):
sentinel = "{ready}\n"
def __init__(self, executable="/usr/bin/exiftool"):
self.executable = executable
def __enter__(self):
self.process = subprocess.Popen(
[self.executable, "-stay_open", "True", "[email protected]", "-"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
return self
def __exit__(self, exc_type, exc_value, traceback):
self.process.stdin.write("-stay_open\nFalse\n")
self.process.stdin.flush()
def execute(self, *args):
args = args + ("-execute\n",)
self.process.stdin.write(str.join("\n", args))
self.process.stdin.flush()
output = ""
fd = self.process.stdout.fileno()
while not output.endswith(self.sentinel):
output += os.read(fd, 4096)
return output[:-len(self.sentinel)]
def get_metadata(self, *filenames):
return json.loads(self.execute("-G", "-j", "-n", *filenames))
Esta clase está escrita como un gestor de contexto para asegurar que el proceso se sale si ha terminado. Se puede utilizar como
with ExifTool() as e:
metadata = e.get_metadata(*filenames)
EDITAR para Python 3: Para conseguir que esto funcione en Python se necesitan 3 dos pequeños cambios. El primero es un argumento adicional para subprocess.Popen
:
self.process = subprocess.Popen(
[self.executable, "-stay_open", "True", "[email protected]", "-"],
universal_newlines=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
La segunda es que hay que decodificar la serie de bytes devuelto por os.read()
:
output += os.read(fd, 4096).decode('utf-8')
usted debe leer la documentación del módulo suprocess: http://docs.python.org/library/subprocess.html – mandel
He cargado una versión más completa del código en mi respuesta a https://github.com/smarnach/pyexiftool. –