import tkinter as tk
from tkinter import
filedialog, colorchooser, Scale, messagebox
from PIL import
Image, ImageTk
import numpy as np
class SealRemoverApp:
def
__init__( self , root):
self .root =
root
self .root.title( "印章抠图工具" )
self .root.geometry( "900x600" )
# 创建界面组件
self .create_widgets()
# 初始化变量
self .original_image =
None
self .processed_image =
None
self .bg_color =
( 255 , 255 , 255 ) # 默认背景色为白色
self .tolerance =
30 # 默认颜色容差
def
create_widgets( self ):
# 控制面板
control_frame =
tk.Frame( self .root, padx = 10 , pady = 10 )
control_frame.pack(side = tk.LEFT, fill = tk.Y)
# 图像显示区域
self .image_frame =
tk.Frame( self .root)
self .image_frame.pack(side = tk.RIGHT, expand = True , fill = tk.BOTH, padx = 10 , pady = 10 )
# 原始图像标签
self .original_label =
tk.Label( self .image_frame, text = "原始图像" , relief = tk.SUNKEN)
self .original_label.pack(side = tk.LEFT, expand = True , fill = tk.BOTH, padx = 5 , pady = 5 )
# 处理后图像标签
self .processed_label =
tk.Label( self .image_frame, text = "处理后图像" , relief = tk.SUNKEN)
self .processed_label.pack(side = tk.RIGHT, expand = True , fill = tk.BOTH, padx = 5 , pady = 5 )
# 按钮控件
tk.Button(control_frame, text = "打开图像" , command = self .open_image).pack(fill = tk.X, pady = 5 )
tk.Button(control_frame, text = "选择背景色" , command = self .choose_bg_color).pack(fill = tk.X, pady = 5 )
tk.Button(control_frame, text = "处理图像" , command = self .process_image).pack(fill = tk.X, pady = 5 )
tk.Button(control_frame, text = "保存结果" , command = self .save_image).pack(fill = tk.X, pady = 5 )
# 容差滑块
tk.Label(control_frame, text = "颜色容差:" ).pack(anchor = tk.W, pady = ( 10 , 0 ))
self .tolerance_scale =
Scale(control_frame, from_ = 0 , to = 100 , orient = tk.HORIZONTAL,
command = self .update_tolerance)
self .tolerance_scale. set ( 30 )
self .tolerance_scale.pack(fill = tk.X)
def
open_image( self ):
file_path =
filedialog.askopenfilename(filetypes = [( "图像文件" , "*.jpg *.jpeg *.png *.bmp" )])
if not
file_path:
return
try :
self .original_image =
Image. open (file_path)
self .display_image( self .original_image, self .original_label)
self .processed_image =
None
self .processed_label.config(image = '')
except Exception as e:
messagebox.showerror( "错误" , f "无法打开图像: {str(e)}" )
def
choose_bg_color( self ):
color =
colorchooser.askcolor(title = "选择背景色" )[ 0 ]
if color:
self .bg_color =
tuple ( int (c) for
c in color)
def
update_tolerance( self , value):
self .tolerance =
int (value)
def
process_image( self ):
if not
self .original_image:
messagebox.showwarning( "警告" , "请先打开图像" )
return
try :
# 转换为RGBA模式
img =
self .original_image.convert( "RGBA" )
data =
np.array(img)
# 创建背景色范围
lower_bound =
np.array([ max ( 0 , c -
self .tolerance) for
c in
self .bg_color] +
[ 0 ])
upper_bound =
np.array([ min ( 255 , c +
self .tolerance) for
c in
self .bg_color] +
[ 255 ])
# 创建透明度蒙版
mask =
np. all ((data > =
lower_bound) & (data < =
upper_bound), axis = - 1 )
# 应用透明度
data[..., 3 ] =
np.where(mask, 0 , 255 )
# 创建新图像
self .processed_image =
Image.fromarray(data)
self .display_image( self .processed_image, self .processed_label)
except Exception as e:
messagebox.showerror( "错误" , f "处理失败: {str(e)}" )
def
display_image( self , image, label_widget):
# 调整图像大小以适应显示区域
max_size =
( 400 , 400 )
image.thumbnail(max_size, Image.LANCZOS)
# 转换为Tkinter可显示的格式
tk_image =
ImageTk.PhotoImage(image)
# 更新标签
label_widget.config(image = tk_image)
label_widget.image =
tk_image # 保持引用
def
save_image( self ):
if not
self .processed_image:
messagebox.showwarning( "警告" , "没有可保存的图像" )
return
file_path =
filedialog.asksaveasfilename(
defaultextension = ".png" ,
filetypes = [( "PNG文件" , "*.png" ), ( "所有文件" , "*.*" )]
)
if file_path:
try :
self .processed_image.save(file_path, "PNG" )
messagebox.showinfo( "成功" , "图像已保存!" )
except Exception as e:
messagebox.showerror( "错误" , f "保存失败: {str(e)}" )
if __name__ = =
"__main__" :
root =
tk.Tk()
app =
SealRemoverApp(root)
root.mainloop()
|