2012-04-09 16 views
5

Fotoğrafları ve videolarımdan EXIF ​​etiketlerini taramak için exiftool'u arıyorum. Bu bir perl yürütülebilir. Bununla ilgili çıkarmanın en iyi yolu nedir? Bunu yapmak için herhangi bir Python kütüphanesi var mı? Veya doğrudan çalıştırılabilir dosyayı çağırıp çıktıyı ayrıştırmalı mıyım? (İkincisi kirli görünüyor.) Teşekkürler.Bir python komut dosyasından exiftool çağırın.

Sormamın nedeni şu an için video desteği olmayan pyexiv2'yi kullanıyorum. Perl'in exiftool görüntüleri ve videoları için çok geniş bir desteğe sahip ve ben onu kullanmak istiyorum.

+1

Sen suprocess modülünün docs okumalısınız: http:/

self.process = subprocess.Popen( [self.executable, "-stay_open", "True", "[email protected]", "-"], universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

ikinci Eğer os.read() tarafından döndürülen bayt dizisi deşifre olması: İlk subprocess.Popen ek bir argümandır /docs.python.org/library/subprocess.html – mandel

+1

https://github.com/smarnach/pyexiftool adresindeki cevabımda kodun daha eksiksiz bir sürümünü yükledim. –

cevap

18

Her görüntü için yeni bir işlem başlatmayı önlemek için, -stay_open bayrağını kullanarak exiftool başlatmalısınız. Daha sonra stdin üzerinden prosese komut gönderebilir ve çıktıyı stdout'ta okuyabilirsiniz. ExifTool, meta verileri okumak için muhtemelen en iyi seçenek olan JSON çıktısını destekler.

exiftool işlemini başlatan ve bu işleme komut göndermek için execute() yöntemini içeren basit bir sınıf.

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

Bu sınıf bitirdiniz eğer çıkıldığında süreci sağlamak için bir bağlam yöneticisi olarak yazılır: Ben de JSON biçiminde meta okumak için get_metadata() dahil. Bu 3 iki küçük değişiklik gerektiğini piton çalışmaya almak için : Sen piton 3

with ExifTool() as e: 
    metadata = e.get_metadata(*filenames) 

DÜZENLEME olarak kullanabilirsiniz.

output += os.read(fd, 4096).decode('utf-8') 
+0

Teşekkürler, bu çok yardımcı oldu. Komutları exiftool'e nasıl geçirebilirim, böylece çalıştırılabilir "açık kalır mı?" Uygulamayı parseImage() adlı bir işleve koyarsam, işlev çağrıldığında her seferinde yeniden açılmasın mı? – ensnare

+0

@ensnare: Biraz kod ekledim. Kodu birkaç nane içinde geliştireceğim. –

+0

Yup, bu harika. Çok teşekkürler. – ensnare

İlgili konular