Để tránh khởi chạy quy trình mới cho từng hình ảnh, bạn nên bắt đầu exiftool
bằng cờ -stay_open
. Sau đó bạn có thể gửi lệnh cho quá trình thông qua stdin, và đọc đầu ra trên stdout. ExifTool hỗ trợ đầu ra JSON, có lẽ là tùy chọn tốt nhất để đọc siêu dữ liệu.
Đây là một lớp đơn giản khởi chạy quy trình exiftool
và có phương thức execute()
để gửi lệnh đến quy trình đó. Tôi cũng bao gồm get_metadata()
để đọc các siêu dữ liệu ở định dạng 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))
Lớp này được viết như một người quản lý bối cảnh để đảm bảo quá trình được thoát nếu bạn đang thực hiện. Bạn có thể sử dụng nó như
with ExifTool() as e:
metadata = e.get_metadata(*filenames)
EDIT cho python 3: Để có được điều này để làm việc trong python 3 hai thay đổi nhỏ là cần thiết. Đầu tiên là một cuộc tranh cãi bổ sung cho subprocess.Popen
:
self.process = subprocess.Popen(
[self.executable, "-stay_open", "True", "[email protected]", "-"],
universal_newlines=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Thứ hai là bạn phải giải mã loạt byte trả về bởi os.read()
:
output += os.read(fd, 4096).decode('utf-8')
Bạn nên đọc các tài liệu của các mô-đun suprocess: http://docs.python.org/library/subprocess.html – mandel
Tôi đã tải lên phiên bản hoàn chỉnh hơn của mã trong câu trả lời của mình cho https://github.com/smarnach/pyexiftool. –