diff --git a/SnailPDF/bin/gsdll64.dll b/SnailPDF/bin/gsdll64.dll new file mode 100644 index 0000000..0c19c80 Binary files /dev/null and b/SnailPDF/bin/gsdll64.dll differ diff --git a/SnailPDF/bin/gsdll64.lib b/SnailPDF/bin/gsdll64.lib new file mode 100644 index 0000000..bf25f8e Binary files /dev/null and b/SnailPDF/bin/gsdll64.lib differ diff --git a/SnailPDF/bin/gswin64.exe b/SnailPDF/bin/gswin64.exe new file mode 100644 index 0000000..b00e821 Binary files /dev/null and b/SnailPDF/bin/gswin64.exe differ diff --git a/SnailPDF/bin/gswin64c.exe b/SnailPDF/bin/gswin64c.exe new file mode 100644 index 0000000..0403943 Binary files /dev/null and b/SnailPDF/bin/gswin64c.exe differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..bf1a417 --- /dev/null +++ b/main.py @@ -0,0 +1,160 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox +import os +import subprocess +import threading + +# 拖拽支持(Windows) +try: + from tkinterdnd2 import DND_FILES, TkinterDnD + DND_AVAILABLE = True +except: + DND_AVAILABLE = False + + +class PDFCompressorApp: + def __init__(self, root): + self.root = root + self.root.title("Snail PDF压缩工具") + self.root.geometry("650x450") + + self.files = [] + self.quality_map = { + "极限压缩(低质量)": "/screen", + "标准压缩(推荐)": "/ebook", + "高质量(打印)": "/printer" + } + + self.create_widgets() + + def create_widgets(self): + frame = tk.Frame(self.root) + frame.pack(fill="both", expand=True, padx=10, pady=10) + + # 文件列表 + self.listbox = tk.Listbox(frame, height=12) + self.listbox.pack(fill="both", expand=True) + + # 拖拽支持 + if DND_AVAILABLE: + self.listbox.drop_target_register(DND_FILES) + self.listbox.dnd_bind("<>", self.drop_files) + + # 按钮区 + btn_frame = tk.Frame(frame) + btn_frame.pack(pady=5) + + tk.Button(btn_frame, text="添加文件", command=self.add_files).pack(side="left", padx=5) + tk.Button(btn_frame, text="添加文件夹", command=self.add_folder).pack(side="left", padx=5) + tk.Button(btn_frame, text="清空", command=self.clear_files).pack(side="left", padx=5) + + # 压缩质量 + tk.Label(frame, text="压缩质量:").pack() + self.quality = tk.StringVar(value="标准压缩(推荐)") + ttk.Combobox( + frame, + textvariable=self.quality, + values=list(self.quality_map.keys()) + ).pack() + + # 进度条 + self.progress = ttk.Progressbar(frame, length=600) + self.progress.pack(pady=10) + + # 状态 + self.status = tk.Label(frame, text="等待开始") + self.status.pack() + + # 开始按钮 + tk.Button(frame, text="开始压缩", bg="green", fg="white", + command=self.start).pack(pady=10) + + def add_files(self): + files = filedialog.askopenfilenames(filetypes=[("PDF Files", "*.pdf")]) + self.add_to_list(files) + + def add_folder(self): + folder = filedialog.askdirectory() + if folder: + pdfs = [os.path.join(folder, f) for f in os.listdir(folder) if f.lower().endswith(".pdf")] + self.add_to_list(pdfs) + + def add_to_list(self, files): + for f in files: + if f not in self.files: + self.files.append(f) + self.listbox.insert(tk.END, f) + + def drop_files(self, event): + files = self.root.tk.splitlist(event.data) + self.add_to_list(files) + + def clear_files(self): + self.files.clear() + self.listbox.delete(0, tk.END) + + def start(self): + if not self.files: + messagebox.showwarning("提示", "请先添加PDF文件") + return + + threading.Thread(target=self.compress_all, daemon=True).start() + + def compress_all(self): + gs_path = os.path.join(os.getcwd(), "bin", "gswin64c.exe") + + if not os.path.exists(gs_path): + messagebox.showerror("错误", "未找到 bin/gswin64c.exe(请检查Ghostscript绿色版)打包后的exe文件放置SnailPDF目录下运行") + return + + total = len(self.files) + self.progress["maximum"] = total + + for i, file in enumerate(self.files): + output = file.replace(".pdf", "_compressed.pdf") + + try: + before_size = os.path.getsize(file) + + cmd = [ + gs_path, + "-sDEVICE=pdfwrite", + "-dCompatibilityLevel=1.4", + f"-dPDFSETTINGS={self.quality_map[self.quality.get()]}", + "-dNOPAUSE", + "-dBATCH", + f"-sOutputFile={output}", + file + ] + + subprocess.run( + cmd, + capture_output=True, + text=True, + creationflags=subprocess.CREATE_NO_WINDOW + ) + after_size = os.path.getsize(output) + ratio = (1 - after_size / before_size) * 100 + + self.status.config( + text=f"完成: {os.path.basename(file)} | 压缩率: {ratio:.1f}%" + ) + + except Exception as e: + self.status.config(text=f"失败: {os.path.basename(file)}") + + self.progress["value"] = i + 1 + + messagebox.showinfo("完成", "全部压缩完成!") + + +if __name__ == "__main__": + if DND_AVAILABLE: + root = TkinterDnD.Tk() + else: + root = tk.Tk() + + app = PDFCompressorApp(root) + root.mainloop() + +#打包命令 .\python.exe -m PyInstaller --onefile --windowed --icon=icon.ico --name "SnailSend" .\main.py \ No newline at end of file