创建图片缩放函数时遇AttributeError:'str'对象无copy属性
解决AttributeError: 'str' object has no attribute 'copy'的问题
咱们直接戳中错误根源:你调用resize_image时传了file_path.copy(),但file_path是个字符串类型的文件路径,字符串根本没有copy()方法!更关键的是——resize_image函数需要的是PIL库的Image对象,不是文件路径字符串!
错误拆解
你的resize_image函数第一行就调用了src_image.thumbnail(),这是PIL Image对象专属的方法。你现在传进去的是文件路径字符串,既触发了copy()的属性错误,就算你去掉.copy(),后续也会因为传入类型不匹配而报错。
修正方案
你需要先把文件路径对应的图片转换成PIL Image对象,再传入缩放函数。这里给你两种常用的实现方式:
方式1:直接用PIL打开图片文件
如果是处理单个特定的file_path,直接用Image.open()读取图片即可:
from PIL import Image, ImageOps import matplotlib.pyplot as plt def resize_image(src_image, size=(200,200), bg_color="white"): # 注意:新版PIL中Image.ANTIALIAS已废弃,改用LANCZOS src_image.thumbnail(size, Image.Resampling.LANCZOS) # 创建指定尺寸的背景图 new_image = Image.new("RGB", size, bg_color) # 将缩放后的图片粘贴到背景图中心 paste_pos = (int((size[0] - src_image.size[0]) / 2), int((size[1] - src_image.size[1]) / 2)) new_image.paste(src_image, paste_pos) return new_image # 修正后的调用代码 target_size = (128,128) pad_color = "black" # 先通过文件路径获取PIL Image对象 pil_image = Image.open(file_path) resized_img = resize_image(pil_image, target_size, pad_color) n_h, n_w = resized_img.size print('New size:', n_h, 'x', n_w) imgplot = plt.imshow(resized_img) plt.show()
方式2:把matplotlib读取的数组转成PIL Image
如果你想复用之前用mp_image.imread()读取的image变量(numpy数组),可以把它转换成PIL Image对象:
import numpy as np from PIL import Image # 假设你之前已经用mp_image.imread(file_path)得到了image数组 pil_image = Image.fromarray(np.uint8(image)) resized_img = resize_image(pil_image, target_size, pad_color)
额外优化建议
- 批量处理文件夹图片:可以把缩放逻辑整合到你之前的循环代码里,比如同时展示原图和缩放后的图片:
# 在你原来的文件夹循环中添加缩放逻辑 fig = plt.figure(figsize=(16, 12)) for root, folders, filenames in os.walk(src_folder): image_num = 0 num_folders = len(folders) for folder in sorted(folders): image_num +=1 file_name = os.listdir(os.path.join(root,folder))[0] file_path = os.path.join(root,folder, file_name) # 读取原图并展示 original_img = mp_image.imread(file_path) a=fig.add_subplot(num_folders, 2, image_num*2) a.set_title(f"{folder} (Original)") plt.imshow(original_img) # 读取图片并缩放后展示 pil_image = Image.open(file_path) resized_img = resize_image(pil_image, (128,128), "black") a=fig.add_subplot(num_folders, 2, image_num*2 +1) a.set_title(f"{folder} (Resized)") plt.imshow(resized_img) plt.show()
- 版本兼容:新版PIL库中
Image.ANTIALIAS已被标记为废弃,使用Image.Resampling.LANCZOS可以避免后续版本的兼容性问题。
内容的提问来源于stack exchange,提问作者aalhayali
相关产品推荐
相关产品推荐

