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

基于Python Pillow与Tkinter:如何保留前次编辑效果进行二次图片编辑?

问题描述

使用Python的Pillow与Tkinter编写图片编辑工具时遇到如下问题:上传图片后点击模糊按钮可实现模糊效果,但再点击旋转按钮时,之前的模糊效果会消失。请问如何保留两次编辑的叠加效果?是否必须在每次编辑后将图片保存到单独文件?

原代码
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter.filedialog import askopenfilename,asksaveasfilename
from PIL import Image, ImageTk, ImageFilter, ImageEnhance, ImageOps
import os

my_w = Tk()
my_w.geometry("1000x1000")  # Size of the window
my_w.title('Photo Editing Tool')

def upload_image():
    global img_path, img
    img_path = filedialog.askopenfilename(initialdir=os.getcwd())
    img = Image.open(img_path)
    img.thumbnail((350, 350))
    img = ImageTk.PhotoImage(img)
    canvas2.create_image(300, 210, image=img)
    canvas2.image=img

def rotate_image():
    global img_path, img
    img = Image.open(img_path)
    img.thumbnail((350, 350))
    img = img.rotate(90)
    img = ImageTk.PhotoImage(img)
    canvas2.create_image(300, 210, image=img)
    canvas2.image = img

def blur():
    global img_path, img
    img = Image.open(img_path)
    img.thumbnail((350, 350))
    img = img.filter(ImageFilter.BLUR)
    img = ImageTk.PhotoImage(img)
    canvas2.create_image(300, 210, image=img)
    canvas2.image = img

canvas2 = Canvas(my_w, width="600", height="420", relief=RIDGE, bd=2)
canvas2.place(x=15, y=150)

btn_select = Button(my_w, text="Select Image", bg='white', fg='black',
              font=('ariel 15 bold'), relief=GROOVE, command=upload_image)
btn_select.place(x=100, y=595)

btn_blur = Button(my_w, text="Blur Image", bg='white',fg='black',
                    font=('ariel 15 bold'), relief=GROOVE, command=blur)
btn_blur.place(x=250, y=595)

btn_rotate = Button(my_w, text="Rotate Image", bg='white',fg='black',
                    font=('ariel 15 bold'), relief=GROOVE, command=rotate_image)
btn_rotate.place(x=400, y=595)

my_w.mainloop()
解决方案

核心问题

你当前的代码每次点击编辑按钮时,都会从原始文件重新加载图片,相当于每次编辑都基于原始图片操作,而非上一次编辑后的结果,所以之前的效果会被覆盖。完全不需要每次编辑后保存到单独文件,只需在内存中维护当前编辑状态的PIL图像对象即可。

修改步骤

  1. 新增全局变量current_img,用于保存当前处于编辑状态的PIL Image对象(注意不是Tkinter的PhotoImage,后者仅用于界面显示)。
  2. 上传图片时,将处理后的PIL对象存入current_img,再转换为PhotoImage显示。
  3. 所有编辑操作(模糊、旋转)都基于current_img进行,编辑完成后更新current_img,再转换为PhotoImage更新界面。

修改后的完整代码

from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk, ImageFilter
import os

my_w = Tk()
my_w.geometry("1000x1000")
my_w.title('Photo Editing Tool')

# 全局变量:保存原始路径、当前编辑的PIL图像、用于显示的PhotoImage
img_path = ""
current_img = None
display_img = None

def upload_image():
    global img_path, current_img, display_img
    img_path = filedialog.askopenfilename(initialdir=os.getcwd())
    # 加载原始图片并处理尺寸
    current_img = Image.open(img_path)
    current_img.thumbnail((350, 350))
    # 转换为PhotoImage用于显示
    display_img = ImageTk.PhotoImage(current_img)
    canvas2.create_image(300, 210, image=display_img)
    canvas2.image = display_img

def rotate_image():
    global current_img, display_img
    if current_img is None:
        return  # 未上传图片时不执行
    # 基于当前编辑的图片旋转
    current_img = current_img.rotate(90)
    display_img = ImageTk.PhotoImage(current_img)
    canvas2.create_image(300, 210, image=display_img)
    canvas2.image = display_img

def blur():
    global current_img, display_img
    if current_img is None:
        return  # 未上传图片时不执行
    # 基于当前编辑的图片添加模糊效果
    current_img = current_img.filter(ImageFilter.BLUR)
    display_img = ImageTk.PhotoImage(current_img)
    canvas2.create_image(300, 210, image=display_img)
    canvas2.image = display_img

# 可选:添加保存当前编辑结果的功能
def save_image():
    global current_img
    if current_img is None:
        return
    save_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG Files", "*.png"), ("JPG Files", "*.jpg")])
    if save_path:
        current_img.save(save_path)

canvas2 = Canvas(my_w, width="600", height="420", relief=RIDGE, bd=2)
canvas2.place(x=15, y=150)

btn_select = Button(my_w, text="Select Image", bg='white', fg='black',
              font=('ariel 15 bold'), relief=GROOVE, command=upload_image)
btn_select.place(x=100, y=595)

btn_blur = Button(my_w, text="Blur Image", bg='white',fg='black',
                    font=('ariel 15 bold'), relief=GROOVE, command=blur)
btn_blur.place(x=250, y=595)

btn_rotate = Button(my_w, text="Rotate Image", bg='white',fg='black',
                    font=('ariel 15 bold'), relief=GROOVE, command=rotate_image)
btn_rotate.place(x=400, y=595)

# 添加保存按钮
btn_save = Button(my_w, text="Save Image", bg='white',fg='black',
                    font=('ariel 15 bold'), relief=GROOVE, command=save_image)
btn_save.place(x=550, y=595)

my_w.mainloop()

关键说明

  • current_img始终保存最新的编辑结果,所有后续操作都基于它进行,实现效果叠加。
  • 新增了未上传图片时的判断,避免空对象报错。
  • 可选的保存按钮可以将最终编辑后的图片保存到指定路径,无需中途保存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:50:31