您当前的位置:首页 > 计算机 > 编程开发 > Python

开源:Python印章抠图神器:一键去除图片背景,透明印章轻松生成

时间:06-04来源:作者:点击数:
CDSY,CDSY.XYZ

还在为如何获取透明背景的印章而烦恼?本工具专为解决电子文档盖章难题而生!告别用PS抠图,傻瓜式操作。

核心功能:

双窗口实时对比:原始图像与抠图结果同屏对比

智能背景识别:自定义背景色+容差调节,精准识别背景区域

一键导出透明PNG:完美保留印章主体,背景透明化

快速高效:基于PIL+NumPy加速,秒级处理

使用方法:

点击"打开图像"导入印章图片

使用颜色选择器指定背景色(默认白色)

拖动滑块调整颜色容差(推荐30-50)

点击"处理图像"生成透明背景效果

保存为PNG格式用于电子文档

代码(成品见https://bbs.cdsy.xyz/thread-24190-1-1.html):

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()

 

CDSY,CDSY.XYZ
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐