使用Pillow保存图片时遇Errno 13权限错误(Python+Django)
解决Pillow保存裁剪图片时的Errno 13权限错误
错误原因分析
出现PermissionError: [Errno 13] Permission denied通常有以下几个核心原因:
- 目录创建时机错误,导致保存时目标目录不存在或权限未正确初始化
- 运行Python程序的用户对目标目录无读写权限
- 路径拼接时的转义问题导致实际访问路径异常
- 裁剪函数逻辑缺陷,返回
None时仍执行保存操作
具体修复方案
1. 调整目录创建逻辑
将目录创建操作移至循环外部,确保保存前目录已存在,同时过滤掉无需裁剪的图片:
# 提前创建裁剪目录,用makedirs支持多级目录,exist_ok=True避免重复创建报错 if not os.path.exists(cropped_dir): os.makedirs(cropped_dir, exist_ok=True) for each_image in os.listdir(image_dir): image_path = os.path.join(image_dir, each_image) cropping = crop_image(image_path) # 仅当裁剪结果有效时执行保存 if cropping is not None: save_path = os.path.join(cropped_dir, each_image) cropping.save(save_path, 'jpeg') cropping.close() # 关闭文件句柄,避免资源泄漏
2. 修复系统权限问题
- Windows系统:右键点击
blah-summer-jean目录 → 「属性」→「安全」,给当前运行Python的用户(如登录用户、PyCharm进程用户)添加「写入」「修改」权限 - 避免将目录放在系统保护路径下(如
C:\Program Files),优先选择用户目录下的非保护区域 - 如果使用虚拟环境,确保虚拟环境进程拥有目录的读写权限
3. 用Pathlib优化路径处理
替换手动路径拼接为pathlib,避免转义字符引发的路径异常:
from pathlib import Path # 用Path对象管理路径,自动处理系统分隔符 image_dir = Path('C:/Users/django/PycharmProjects/sassigen/csvs/photos/blah-summer-jean') cropped_dir = image_dir / 'cropped-788x1000' # 创建目录,parents=True自动创建上级目录 cropped_dir.mkdir(parents=True, exist_ok=True) # 遍历目录只处理文件 for each_image in image_dir.iterdir(): if each_image.is_file(): cropping = crop_image(str(each_image)) if cropping is not None: save_path = cropped_dir / each_image.name cropping.save(str(save_path), 'jpeg') cropping.close()
4. 完善裁剪函数逻辑
修复无需裁剪时的返回值,确保文件句柄正常关闭:
def crop_image(image): try: img = Image.open(image) width, height = img.size if width <= 788 and height <= 1000: # 返回原图片副本,避免原文件被占用 result = img.copy() img.close() return result else: # 修正裁剪坐标逻辑,匹配最终788x1000的尺寸 xcenter = img.width / 2 ycenter = img.height / 2 x1 = max(0, int(xcenter - 394)) y1 = max(0, int(ycenter - 500)) x2 = min(img.width, int(xcenter + 394)) y2 = min(img.height, int(ycenter + 500)) image_to_crop = img.crop((x1, y1, x2, y2)) final_image = image_to_crop.resize((788, 1000)) # 关闭所有临时文件句柄 img.close() image_to_crop.close() return final_image except AttributeError: return None except Exception as e: # 异常时确保关闭已打开的文件 if 'img' in locals(): img.close() raise e
内容的提问来源于stack exchange,提问作者Vinh Nguyen
相关产品推荐
相关产品推荐

