从子文件夹中的图像编码元数据

时间:2012-10-29 11:02:08

标签: python encoding metadata

我从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

2 个答案:

答案 0 :(得分:0)

一旦遇到带有“错误”扩展名的文件,

scandirs就会返回。你的目录中有这样的文件吗?你只需要continue。如果要遍历树,请使用os.walk,然后不需要递归。

如果您想要可读输出,您可能希望decodestr对象。另外,请参阅下面的最后一个注释。

各种说明:

  • Image.open行旁边的所有内容放入else子句
  • 检查None,如下所示:if exifinfo is None:
  • 类型检查:isinstance(value, str)。这个位很重要,我认为你的任何编码/解码都没有被执行过。

比照:

>>> type('st') == 'str'
False

答案 1 :(得分: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)