0

我从 Python 开始,从一个文件夹开始并在其子文件夹中重复出现的图像中读取元数据的脚本有两个问题。

第一:我只从一个子文件夹获得输出
第二:某些字段的输出是另一种编码,如何让它可读?我尝试了各种解码和编码组合,但没有任何变化

from PIL import Image
from PIL.ExifTags import TAGS
import os
import glob
import sys, codecs

path = '//server/share/folder/'

def get_exif_data(fname):
  ret = {}
  try:
    img = Image.open(fname)
    if hasattr( img, '_getexif' ):
      exifinfo = img._getexif()
    if exifinfo != None:
      for tag, value in exifinfo.items():
        decoded = TAGS.get(tag, tag)
        if type(value) == 'str':
          ret[decoded] = value.encode('latin-1')
        else:
          ret[decoded] = value
  except IOError:
    print 'IOERROR ' + fname
  return ret

def scandirs(path):
  for currentFile in glob.glob( os.path.join(path, '*') ):
    if os.path.isdir(currentFile):
        print '\ngot a directory: ' + currentFile + '\n'
        scandirs(currentFile)
    ext = os.path.splitext(currentFile)[1].lower()
    if ext not in ['.jpg', '.jpeg', '.jfif']:
      return 0
    print currentFile
    print get_exif_data(currentFile)

scandirs(path)

这里是输出示例,注意 MakerNote 的编码内容

#{'YResolution': (180, 1), 41985: 0, 'ResolutionUnit': 2, 41987: 0, 41988: (2272, 2272), 41990: 0, 'Make': 'Canon', 'Flash': 89, 41986: 0, 'DateTime': '2005:10:14 13:10:26', 'MeteringMode': 5, 'XResolution': (180, 1), 
#'MakerNote': '\x0e\x00\x01\x00\x03\x00.\x00\x00\x00\\\x04\x00\x00\x02\x00\x03\x00\x04\x00\x00\x00\xb8\x04\x00\x00\x03\x00\x03\x00\x04\x00\x00\x00\xc0\x04\x00\x00\x04\x00\x03\x00"\x00\x00\x00\xc8\x04\x00\x00\x00\x00\x03\x00\x06\x00\x00\x00\x0c\x05\x00\x00\x00\x00\x03\x00\x04\x00\x00\x00\x18\x05\x00\x00\x12\x00\x03\x00$\x00\x00\x00 \x05\x00\x00\x13\x00\x03\x00\x04\x00\x00\x00h\x05\x00\x00\x06\x00\x02\x00 \x00\x00\x00p\x05\x00\x00\x07\x00\x02\x00\x18\x00\x00\x00\x90\x05\x00\x00\x08\x00\x04\x00\x01\x00\x00\x00\xc6\xe5\x1b\x00\t\x00\x02\x00 \x00\x00\x00\xa8\x05\x00\x00\x10\x00\x04\x00\x01\x00\x00\x00\x00\x00!\x01\r\x00\x03\x00"\x00\x00\x00\xc8\x05\x00\x00\x00\x00\x00\x00\\\x00\x02\x00\x00\x00\x05\x00\x05\x00\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x03\x00\x01\x00\x01@\x00\x00\xff\xff\xff\xff\xaa\x02\xe3\x00 \x00c\x00\xc0\x00\x01\x00\x08 \x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xe0\x08\xe0\x08\x00\x00\x00\x00\x00\x00\x00\x00\xff\x7f\x00\x00\x00\x00\x00\x00\x02\x00\xe3\x00\x1e\x01\xd7\x00$\x01\xdb\x02\x00\x00\x00\x00D\x00\x00\x00\x80\x00X\x00_\x00\xbd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x91\x01\x00\x00c\x00\xc0\x00\x00\x00\x00\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\t\x00\xe0\x08\xa8\x06\xe0\x08\xd4\x00\x99\x01&\x00f\xfe\x00\x00\x9a\x01f\xfe\x00\x00\x9a\x01f\xfe\x00\x00\x9a\x01\xd7\xff\xd7\xff\xd7\xff\x00\x00\x00\x00\x00\x00)\x00)\x00)\x00I\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00IMG:PowerShot S45 JPEG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Firmware Version 1.00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\t\x00]\x01[\x01Z\x01]\x01\\\x01\\\x01]\x01U\x01_\x01\x04\x00\x00\x00\x00\x00z\xff\x00\x00\x00\x00\n\x00\x00\x00\x03\x00\n\x00\xa7\x00\xda\x000\x00\x00\x00\xf9\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\xa3\x00', 'ColorSpace': 1, 'ExifImageWidth': 2272, 'DateTimeDigitized': '2005:10:14 13:10:26', 'ApertureValue': (95, 32), 'UserComment': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'FocalPlaneYResolution': (1704000, 210), 'CompressedBitsPerPixel': (5, 1), 'SensingMethod': 2, 'FNumber': (28, 10), 'DateTimeOriginal': '2005:10:14 13:10:26', 'FocalLength': (227, 32), 'ComponentsConfiguration': '\x01\x02\x03\x00', 'FocalPlaneXResolution': (2272000, 280), 'ExifOffset': 196, 'ExifImageHeight': 1704, 'Model': 'Canon PowerShot S45', 'Orientation': 1, 'ExposureTime': (1, 60), 'FileSource': '\x03', 'MaxApertureValue': (95, 32), 'ExifInteroperabilityOffset': 1572, 'FlashPixVersion': '0100', 'FocalPlaneResolutionUnit': 2, 'YCbCrPositioning': 1, 'ExifVersion': '0220'}

编辑:我管理了步行部分,但仍然在编码中挣扎

if isinstance(value, str):
  ret[decoded] = value.decode('utf-8')

错误

Unexpected errorTraceback (most recent call last):: <type 'exceptions.UnicodeDecodeError'>
File "c:\python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xb8 in position 22: invalid start byte
4

2 回答 2

0

scandirs一旦遇到带有“错误”扩展名的文件,就会返回。你的目录中有这样的文件吗?你只需要continue. 如果要遍历树使用os.walk,则不需要递归。

decode如果您想要可读的输出,您可能想要str反对。另外,请参阅下面的最后一个注释。

各种注释:

  • 把所有东西都放在Image.open从句else
  • 像这样检查Noneif exifinfo is None:
  • 类型检查:isinstance(value, str). 这一点很重要,我认为您的任何编码/解码实际上都没有被执行过。

参照:

>>> type('st') == 'str'
False
于 2012-10-29T11:06:12.970 回答
0
def find_images(arg, directory, files):
    for file_ in files:
        filename, extension = os.path.splitext(file_)
        if extension in ['.jpeg', '.jpg', '.png']:
            get_exif_data(os.path.join(directory, file_))

os.path.walk(path, find_image, None)
于 2012-10-29T11:26:41.943 回答