python - 从 python 脚本调用 exiftool?

标签 python exiftool

我想使用 exiftool 从我的照片和视频中扫描 EXIF 标签。它是一个 perl 可执行文件。对此进行推断的最佳方法是什么?是否已经有任何 Python 库可以执行此操作?或者我应该直接调用可执行文件并解析输出吗? (后者看起来很脏。)谢谢。

我问的原因是因为我目前使用的是pyexiv2,它不支持视频。 Perl 的 exiftool 对图像和视频有非常广泛的支持,我想使用它。

最佳答案

为避免为每个图像启动新进程,您应该使用 -stay_open 启动 exiftool旗帜。然后您可以通过 stdin 向进程发送命令,并读取 stdout 上的输出。 ExifTool 支持 JSON 输出,这可能是读取元数据的最佳选择。

这是一个启动 exiftool 进程并使用 execute() 方法向该进程发送命令的简单类。我还包括 get_metadata() 以读取 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",  "-@", "-"],
            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))

此类被编写为上下文管理器,以确保在完成后退出进程。您可以将其用作

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

为 python 3 编辑: 为了让它在 python 3 中工作,需要进行两个小的更改。第一个是 subprocess.Popen 的附加参数:

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

第二个是你必须解码 os.read() 返回的字节序列:

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

针对 Windows 的编辑:要使其在 Windows 上运行,需要将 sentinel 更改为 "{ready}\r\n",即

sentinel = "{ready}\r\n"

否则程序将挂起,因为 execute() 中的 while 循环不会停止

关于python - 从 python 脚本调用 exiftool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10075115/

相关文章:

python - 需要使用 Keras 的 model.predict 的帮助

python - 按索引雕刻二维 numpy 数组

haskell - 从 Exiftool 提取参数到 haskell

hadoop - 是否可以使用 Exiftool 获取 Hdfs 图像/视频文件元数据

windows - 使用 EXIF 增加序列号

python - 如何从 Python 启动 Casperjs 脚本

python - __add__ 和 + 运算符之间的性能差异

python - 部署在 Pythonanywhere 上的 Web2py 不会自动获取函数 View

image - 在命令行上从图像中删除所有元数据