You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter使用PIL保存图片时PhotoImage无save属性错误如何解决

错误诱因

报错的核心原因有两个:

  1. 类型不匹配:save()是PIL库Image对象的专属方法,你在fileSave函数中把self.img赋值为self.image_image_3,后者是Tkinter的PhotoImage类型,本身没有save方法,调用后直接触发AttributeError。
  2. 赋值逻辑错误:fileOpen函数执行时已经把用户选择的原始图片以PIL Image类型存入了self.img变量,但fileSave中强行覆盖了这个变量,直接丢失了可正常执行保存操作的图片对象。另外你代码中赋值的self.image_image_3是页面初始化时的静态占位图,和用户打开的待保存图片没有关联。
修复方案

根据保存需求分为两种场景,按需选择即可:

场景1:保存用户打开的原始图片

直接修改fileSave函数逻辑,去掉错误的变量覆盖代码,同时将文件保存模式调整为二进制模式避免图片损坏,修改后代码如下:

def fileSave(self):
    # 直接使用fileOpen中已经赋值的PIL Image类型的self.img,不要覆盖
    filename = filedialog.asksaveasfilename(
        title='选择保存路径',
        defaultextension=".png",
        filetypes=[ ( "图片文件",("*.jpg","*.bmp", "*.jpeg", "*.png", "*.gif") ), ("所有文件", ("*.*"))]
    )
    if filename:
        self.img.save(filename)

场景2:保存界面上显示的、经过resize处理后的图片

你在fileOpen中已经把resize后的图片存入了self.resized_image实例变量,直接调用这个变量的save方法即可:

def fileSave(self):
    filename = filedialog.asksaveasfilename(
        title='选择保存路径',
        defaultextension=".png",
        filetypes=[ ( "图片文件",("*.jpg","*.bmp", "*.jpeg", "*.png", "*.gif") ), ("所有文件", ("*.*"))]
    )
    if filename:
        self.resized_image.save(filename)

补充说明

如果你坚持使用asksaveasfile而非asksaveasfilename,需要将打开模式改为wb(二进制写入),操作完成后手动关闭文件对象,避免资源泄漏:

def fileSave(self):
    file = filedialog.asksaveasfile(
        mode='wb',
        title='选择保存路径',
        defaultextension=".png",
        filetypes=[ ( "图片文件",("*.jpg","*.bmp", "*.jpeg", "*.png", "*.gif") ), ("所有文件", ("*.*"))]
    )
    if file:
        self.img.save(file)
        file.close()

修改后即可支持PNG、BMP、JPG等多种格式的导出,PIL会根据你选择的文件后缀自动适配编码格式。

内容的提问来源于stack exchange,提问作者AlvaroSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:06:04