Python读取TIFF元信息并按规则归类文件报错求助
解决TIFF图片按元信息归类的代码报错问题
需求说明
- 读取指定文件夹内的TIFF图片
- 提取图片中的
Resolution、Binning Mode、IntegrationLevel元信息 - 根据提取的信息创建层级嵌套文件夹(不存在则自动创建)
- 将原图片复制到对应的层级目录中
原报错代码及问题
以下是最初尝试的代码,运行时触发KeyError:
import os import shutil import exifread from PIL import Image from pathlib import Path # Define the input and output directories input_dir = Path('the origin') output_dir = Path('output folder') # Loop through all the files in the input directory for file in os.listdir(input_dir): if file.endswith('.tiff'): # Read the image file img_path = input_dir / file # Get the image metadata using exifread with open(img_path, 'rb') as f: tags = exifread.process_file(f) info = {} for tag in tags: if tag.startswith('Image '): key = tag.split(' ')[1] value = tags[tag].values info[key] = value # Print the keys in the info dictionary print(info.keys()) resolution = int(info['Resolution']) binning_mode = info['BinningMode'] integration_level = float(info['IntegrationLevel']) # Create the output directory based on the image data output_subdir = output_dir / f"res_{resolution}" / f"bin_{binning_mode}" / f"il_{integration_level}" output_subdir.mkdir(parents=True, exist_ok=True) # Copy the image file to the output directory shutil.copy(img_path, output_subdir / file)
错误信息
> resolution = int(info['Resolution']) ~~~~^^^^^^^^^^^^^^ KeyError: 'Resolution' dict_keys(['ImageWidth', 'ImageLength', 'BitsPerSample', 'Compression', 'PhotometricInterpretation', 'ImageDescription', 'StripOffsets', 'SamplesPerPixel', 'RowsPerStrip', 'StripByteCounts', 'XResolution', 'YResolution', 'ResolutionUnit', 'SampleFormat'])
问题原因:exifread仅提取了标准EXIF标签,而目标元信息属于TIFF的自定义字段,无法通过该工具获取。
可正常获取元信息的参考代码
使用PIL的getexif()方法可以正确读取到目标自定义元信息:
import os from PIL import Image from PIL.ExifTags import TAGS # specify the directory path where the images are stored directory = "image path" # loop through all the files in the directory for filename in os.listdir(directory): if filename.endswith(".tiff"): # construct the full file path filepath = os.path.join(directory, filename) # open the image image = Image.open(filepath) # extracting the exif metadata exifdata = image.getexif() # looping through all the tags present in exifdata for tagid in exifdata: # getting the tag name instead of tag id tagname = TAGS.get(tagid, tagid) # passing the tagid to get its respective value value = exifdata.get(tagid) # printing the final result print(f"{filename} - {tagname}: {value}")
通过这段代码获取到的目标元信息示例:
- integrationLevel="2"
- resolution=23000
- binningMode="BackwardCompatible"
修复后的完整代码
基于PIL重写代码,实现需求:
import shutil from pathlib import Path from PIL import Image from PIL.ExifTags import TAGS # 定义输入输出目录 input_dir = Path('the origin') output_dir = Path('output folder') # 遍历所有TIFF文件(包括.tif后缀) for img_path in input_dir.glob('*.tif*'): # 打开图片并读取EXIF元信息 with Image.open(img_path) as img: exifdata = img.getexif() # 提取目标字段 target_tags = {} for tagid in exifdata: tagname = TAGS.get(tagid, tagid) # 匹配目标字段名(注意大小写与实际输出一致) if tagname in ['resolution', 'binningMode', 'integrationLevel']: target_tags[tagname] = exifdata.get(tagid) # 转换字段类型 resolution = int(target_tags['resolution']) binning_mode = target_tags['binningMode'] integration_level = float(target_tags['integrationLevel']) # 创建层级目录 output_subdir = output_dir / f"res_{resolution}" / f"bin_{binning_mode}" / f"il_{integration_level}" output_subdir.mkdir(parents=True, exist_ok=True) # 复制图片到目标目录 shutil.copy(img_path, output_subdir / img_path.name)
修复要点
- 替换exifread为PIL的
getexif(),确保能读取到自定义元信息 - 使用
Path.glob('*.tif*')遍历所有TIFF文件(兼容.tif和.tiff后缀) - 遍历EXIF标签时精准匹配目标字段名(注意大小写与实际输出一致)
- 对字段值进行类型转换,适配目录命名需求
- 保留Path路径处理的简洁性,避免字符串拼接路径的问题
内容的提问来源于stack exchange,提问作者Neko Lim
相关产品推荐
相关产品推荐

