2012-10-29 10 views
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) 

這裏輸出的一個樣本,發現製造商註釋的編碼內容

#{'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\[email protected]\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 
+0

如果你想通過一個目錄(遞歸)走,爲什麼不使用'os.walk'? – Evert

+0

如果它不是'str',那麼值的'type()'是什麼? – Evert

+0

不可讀的字段有str,所以我只嘗試對它們進行解碼/編碼 – peter

回答

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) 
+0

感謝步行sugegstion,現在這部分工作,仍然努力與編碼部分 – peter

0

scandirs遇到帶有「錯誤」擴展名的文件時返回。你的目錄中有這樣的文件嗎?你只需要continue。如果你想遍歷樹使用os.walk,然後你不需要遞歸。

如果你想要可讀輸出,你可能想要decodestr對象。另請參閱下面的最後一個註釋。

各種注意事項:

  • 把一切旁邊Image.open線爲else條款
  • 支票None這樣的:if exifinfo is None:
  • 類型檢查:isinstance(value, str)。這一點很重要,實際上,我認爲你的編碼/解碼沒有被執行過。

參見:

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

謝謝,我管理着行走的部分,但仍然與編碼鬥爭,請求檢查我的更新問題 – peter

+0

@peter:你的if條件是錯誤的。這不是你如何做類型檢查! – SilentGhost

+0

你的意思是我的更新嗎?如果isinstance(value,str): 那麼我應該使用什麼? – peter

相關問題