Python批量调整10MB以上图片脚本报错排查求助
批量处理大尺寸图片脚本报错排查
我编写了Python脚本,用于批量处理指定目录及子目录中大小超过10MB的.png、.jpeg、.jpg格式图片,在Jupyter Notebook中运行时,出现「Unable to resize C:\intersteller\StaticFileBasePath\3.jpg. Skipping.」错误。以下是我的脚本代码及运行结果,请帮忙排查报错根因:
脚本代码
from PIL import Image import os, sys import PIL import glob dir_path = r'C:\intersteller\StaticFileBasePath' def resize_im(path): for foldername, subfolders, photos in os.walk(dir_path): for filename in photos: if filename.endswith(('jpeg', 'jpg', 'png')) and os.path.getsize(os.path.join(foldername, filename))>10000000: print(foldername + '\\' + filename) parent_dir = os.path.dirname(dir_path) img_name = os.path.basename(dir_path).split('.')[0] img_extension = os.path.basename(dir_path).split('.')[1] if img_extension.upper() not in ['PNG', 'JPG', 'JPEG']: print('invalid extension >>', img_extension) return img = Image.open(dir_path); width, height = img.size; asp_rat = width/height; # Enter new width (in pixels) new_width = 2775; # Enter new height (in pixels) new_height = 3700; new_asp_rat = new_width/new_height; if (new_asp_rat == asp_rat): img = img.resize((new_width, new_height), Image.ANTIALIAS); # adjusts the height to match the width # NOTE: if you want to adjust the width to the height, instead -> # uncomment the second line (new_width) and comment the first one (new_height) else: new_height = round(new_width / asp_rat); #new_width = round(new_height * asp_rat); img = img.resize((new_width, new_height), Image.ANTIALIAS); if img_extension.upper() == 'PNG': print('png deteced') img.save(os.path.join(parent_dirm + 'new', img_name + 'resized.png'), 'PNG', quality=50) else: img.save(os.path.join(parent_dirm + 'new', img_name + 'resized.jpeg'), 'JPEG', quality=50) def resize_all(mydir): for foldername, subfolders, photos in os.walk(dir_path): for filename in photos: if filename.endswith(('jpeg', 'jpg', 'png')) and os.path.getsize(os.path.join(foldername, filename))>10000000: try: full_path = os.path.join(foldername, filename) resize_im(full_path) except Exception as e: print('Unable to resize %s. Skipping.' % full_path) if __name__ == '__main__': resize_all(dir_path)
运行结果
C:\intersteller\StaticFileBasePath\3.jpg Unable to resize C:\intersteller\StaticFileBasePath\3.jpg. Skipping. C:\intersteller\StaticFileBasePath\3.jpg Unable to resize C:\intersteller\StaticFileBasePath\4.jpg. Skipping.
报错根因及修正方案
核心错误点
- 函数参数未被使用:
resize_im函数接收的path参数完全没用到,反而在函数内部重新遍历根目录dir_path,导致重复触发处理逻辑;且核心的Image.open(dir_path)是尝试打开文件夹而非目标图片,直接引发文件打开错误。 - 图片信息提取错误:
img_name和img_extension错误地从根目录路径提取,而非当前处理的图片文件名——根目录是文件夹,split('.')操作会得到错误结果,甚至引发索引越界。 - 变量拼写错误:保存路径中使用了未定义的
parent_dirm,正确变量应为parent_dir。 - 保存路径未创建:代码中直接使用
parent_dir + 'new'作为保存目录,但该目录若不存在会导致保存失败。 - 废弃API使用:
Image.ANTIALIAS在新版PIL/Pillow中已被废弃,需替换为Image.Resampling.LANCZOS。
修正后的脚本
from PIL import Image import os dir_path = r'C:\intersteller\StaticFileBasePath' # 定义保存的目标目录,可根据需求调整 save_dir = os.path.join(os.path.dirname(dir_path), 'resized_images') os.makedirs(save_dir, exist_ok=True) # 确保目录存在 def resize_im(img_full_path): # 获取图片文件名和扩展名 filename = os.path.basename(img_full_path) img_name, img_extension = os.path.splitext(filename) img_extension = img_extension.lstrip('.').upper() # 二次校验扩展名(外层已过滤,可选) if img_extension not in ['PNG', 'JPG', 'JPEG']: print(f'无效扩展名 >> {img_extension},跳过 {img_full_path}') return try: with Image.open(img_full_path) as img: width, height = img.size asp_rat = width / height new_width = 2775 new_height = 3700 new_asp_rat = new_width / new_height # 浮点比较避免精度问题,调整尺寸保持原比例 if not abs(new_asp_rat - asp_rat) < 1e-6: new_height = round(new_width / asp_rat) # 使用新版调整尺寸API resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) # 构造保存路径并保存 if img_extension == 'PNG': save_path = os.path.join(save_dir, f'{img_name}_resized.png') resized_img.save(save_path, 'PNG', quality=50) else: save_path = os.path.join(save_dir, f'{img_name}_resized.jpeg') resized_img.save(save_path, 'JPEG', quality=50) print(f'已处理并保存:{save_path}') except Exception as e: print(f'处理 {img_full_path} 失败:{str(e)}') def resize_all(mydir): for foldername, _, photos in os.walk(mydir): for filename in photos: if filename.lower().endswith(('jpeg', 'jpg', 'png')): img_full_path = os.path.join(foldername, filename) # 检查文件大小是否超过10MB(10*1024*1024=10485760字节) if os.path.getsize(img_full_path) > 10485760: resize_im(img_full_path) if __name__ == '__main__': resize_all(dir_path)
内容的提问来源于stack exchange,提问作者kenson kf
相关产品推荐
相关产品推荐

