Python中的EXIF信息 - libexif

1 投票
1 回答
934 浏览
提问于 2025-04-18 02:16

我一直在用pyexiv2这个工具来读取JPEG文件中的exif信息,发现有一个特别的标签——曝光时间(ExposureTime)——在exiv2和另一个exif库libexif中报告的方式不一样。

我试过的所有基于exiv2的工具都会把曝光时间标签简化成一个“有理数”,比如0/1、0或者类似的东西。而基于libexif的工具(特别是一个叫“exif”的工具)则会给出更详细的结果,比如“1/-21474836秒”,而这个结果是针对同一张图片的同一个标签。

首先,我想了解一下:是什么原因导致了这个差异?我假设libexif的结果是正确的。

其次,假设libexif报告的更详细的标签是正确的,我想在Python中获取这个值,但到目前为止,我看到的EXIF工具(比如pyexiv2)似乎都无法做到这一点。我有没有忽略什么工具或方法呢?

我偶然发现了一个可能的解决方案,就是在Python中使用libexif的C库,配合ctypes,正如之前回答过的问题中提到的那样——不过我找不到具体的例子来说明我该怎么做。

非常感谢任何帮助!谢谢!

1 个回答

-1

如果这对你有帮助的话,我最近做了一些小技巧,来设置缺失的镜头和光圈信息,因为我使用的是手动镜头。此外,我还计算了实际的绝对曝光值,以便后续的HDR处理工具(HDR Luminace)能够自动获取这些信息。为了安全起见,我在下面注释掉了“写入”操作。这个过程应该比较容易理解。

顶部的文件部分列出了当前文件夹中需要处理的文件(这里是所有的*.ARW文件,也就是索尼的原始文件)。你可以根据需要调整文件模式和路径。

#!/usr/bin/env python
import os
import time
import array
import math

# make file list (take all *.ARW files in current folder)
files = [f for f in os.listdir(".") if f.endswith(".ARW")]
files.sort()   # just to be nice

# have a dict. of tags to work with in particular
tags = {'Aperture':10., 'Exposure Time ':1./1250, 'Shutter Speed':1./1250, 'ISO':200., 'Stops Above Base ISO':0., 'Exposure Compensation':0. }

# arbitrary chosen base EV to get final EV compensation numbers into +/-10 range
EVref = math.log (math.pow(tags['Aperture'],2.0)/tags['Shutter Speed'], 2.0) - 4
print ('EVref=', EVref)

for f in files:
    print (f)
    meta=os.popen("exiftool "+f).readlines()
    for tag in meta:
        set = str(tag).rstrip("\n").split(":")
        for t,x in tags.items():
            if str(set[0]).strip(" ") == t:
                tags[t] = float ( str(os.popen("calc -- "+set[1]).readlines()).strip("[]'~\\t\\n"))
                print (t, tags[t], set[1])

    ev = math.log (math.pow(tags['Aperture'],2.0)/tags['Shutter Speed'], 2.0)
    EV = EVref - ev + tags['Stops Above Base ISO']
    print ('EV=', EV)
#  uncomment/edit to update EXIF in place:
#    os.system('exiftool -ExposureCompensation='+str(EV)+' '+f)
#    os.system('exiftool -FNumber=10 '+f)
#    os.system('exiftool -FocalLength=1000.0 '+f)
#    os.system('exiftool -FocalLengthIn35mmFormat=1000.0 '+f)

撰写回答