使用该程序将【JPG/PDF文件】和【ZIP文件】合并,合并后的文件在【.jpg/.pdf】和【.zip】的后缀下均可正常读取,从而隐藏zip文件。
编译后单文件下载链接
蓝奏云
https://o-zwz-o.lanzouq.com/iBCx91w9ipqh 密码:52pj
1、拼接后的文件不可再次修改,否则会存在不可知的问题;
2、图片形态的拼接后文件,在QQ等平台直接发送时,注意勾选“发送原图”,否则图片在压缩时,zip部分内容将丢失。
使用Windows下的copy /b指令,将两个文件以二进制形式直接拼接为一个文件,拼接后的文件在两种后缀名下均可以正常读取。
import tkinter as tk from tkinter import filedialog, messagebox from datetime import datetime import os from tkinter import font from tkinter import PhotoImage import base64 # 程序窗口图标base64编码 base64_string = """ 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 """ log = """欢迎使用文件隐藏程序! 该程序使用Windows下的“copy /b”命令行指令, 将JPG/PDF文件和ZIP文件以二进制模式合并为一个文件, 使合并后的文件在.jpg/.pdf和.zip后缀下均可正常读取; 达到隐藏zip文件的效果。 本软件仅供学习和交流,不得在商业环境下使用。 """ def time(): now = datetime.now() time_str = now.strftime("%y-%m-%d %H:%M:%S") return time_str def insert_log(msg, info = 'Info', is_log = 1): # 保存当前的只读状态 is_disabled = text_display.cget('state') == 'disabled' # 如果当前是只读状态,则暂时取消只读 if is_disabled: text_display.config(state='normal') if is_log: text_display.insert(tk.END, f"{time()} | {info} | {msg}\n") else: text_display.insert(tk.END, f"{msg}\n") # 如果之前是只读状态,则恢复只读 if is_disabled: text_display.config(state='disabled') def choose_jpg(): file_path = filedialog.askopenfilename( title="选择一个JPG/PDF文件", filetypes=[("JPG文件", "*.jpg"), ("PDF文件", "*.pdf")] ) if file_path: file_path = ''.join(['\\' if char == '/' else char for char in file_path]) entry1.delete(0, tk.END) entry1.insert(0, file_path) def choose_zip(): file_path = filedialog.askopenfilename( title="选择一个ZIP文件", filetypes=[("ZIP文件", "*.zip")] ) if file_path: file_path = ''.join(['\\' if char == '/' else char for char in file_path]) entry2.delete(0, tk.END) entry2.insert(0, file_path) def choose_folder(): folder_path = filedialog.askdirectory(title="选择一个文件夹") if folder_path: folder_path = ''.join(['\\' if char == '/' else char for char in folder_path]) entry3.delete(0, tk.END) entry3.insert(0, folder_path) def merge_files(): jpg_path = entry1.get() zip_path = entry2.get() folder_path = entry3.get() # 检查第一个和第二个输入框是否为空 if not jpg_path or not zip_path: insert_log("未选择JPG/PDF和ZIP文件!", "Error") return # 检查文件是否存在 if not os.path.isfile(jpg_path): insert_log("JPG/PDF文件不存在!", "Error") return if not os.path.isfile(zip_path): insert_log("ZIP文件不存在!", "Error") return # 获取文件名(不包括扩展名) file_name = os.path.splitext(os.path.basename(jpg_path))[0] output_path = '' # 构建输出文件路径 if os.path.splitext(os.path.basename(jpg_path))[1] == 'jpg': output_path = os.path.join(folder_path, file_name + "-merged.jpg") # 修改输出文件扩展名为.jpg else: output_path = os.path.join(folder_path, file_name + "-merged.pdf") # 修改输出文件扩展名为.pdf if os.path.exists(output_path): insert_log(f"{output_path}已存在!请移除或重命名该文件。", "Error") return # 执行合并命令 try: cmd = f'copy /b "{jpg_path}"+"{zip_path}" "{output_path}"' print(cmd) os.system(cmd) if os.path.exists(output_path): insert_log("文件合并成功!", "Success") insert_log(f"输出文件已保存在:{output_path}", is_log=0) return else: insert_log("出现未知错误。", "Error") return except Exception as e: insert_log(f"出现错误:{e}", "Error") # 获取当前文件夹的绝对路径 current_folder = os.path.abspath(".") # 创建主窗口 root = tk.Tk() root.title("文件隐藏程序") # 设置字体 custom_font = font.Font(family="黑体", size=10, weight="normal") # 将 base64 编码图片设置为窗口图标 image_data = base64.b64decode(base64_string) icon = PhotoImage(data=image_data) root.iconphoto(True, icon) # 创建并布局Frames和组件 frames = [tk.Frame(root) for _ in range(5)] for i, frame in enumerate(frames): frame.pack(pady=10, fill='x' if i < 3 else 'both', expand=True) # 第一个Frame label1 = tk.Label(frames[0], text="JPG/PDF 文件路径", width=16) entry1 = tk.Entry(frames[0], font=custom_font, width=25) button1 = tk.Button(frames[0], text="选择文件", command=choose_jpg, width=10) label1.grid(row=0, column=0, padx=5, pady=5, sticky='e') entry1.grid(row=0, column=1, padx=5, pady=5) button1.grid(row=0, column=2, padx=5, pady=5) # 第二个Frame label2 = tk.Label(frames[1], text="ZIP 文件路径", width=16) entry2 = tk.Entry(frames[1], font=custom_font, width=25) button2 = tk.Button(frames[1], text="选择文件", command=choose_zip, width=10) label2.grid(row=0, column=0, padx=5, pady=5, sticky='e') entry2.grid(row=0, column=1, padx=5, pady=5) button2.grid(row=0, column=2, padx=5, pady=5) # 第三个Frame label3 = tk.Label(frames[2], text="输出文件路径", width=16) entry3 = tk.Entry(frames[2], font=custom_font, width=25) button3 = tk.Button(frames[2], text="选择文件夹", command=choose_folder, width=10) label3.grid(row=0, column=0, padx=5, pady=5, sticky='e') entry3.grid(row=0, column=1, padx=5, pady=5) button3.grid(row=0, column=2, padx=5, pady=5) # 第四个Frame - 日志显示区 text_display = tk.Text(frames[3], height=20,width=56, wrap='word', font=custom_font) text_display.grid(row=0, column=0, padx=5, pady=5, sticky='nsew') text_display.insert('end', log) text_display.config(state='disabled') # 第五个Frame - 文件合并按钮 button_merge = tk.Button(frames[4], text="隐藏文件", command=merge_files, height=2, width=20) button_merge.pack(expand=True, fill='x', padx=10, pady=10) # 第三个输入框自动填充当前文件夹的绝对路径 entry3.insert(0, current_folder) insert_log("软件启动成功。", "Info") # 运行主循环 root.mainloop()
使用pyinstaller编译此代码为单个exe文件:
pyinstaller --onefile --ico=favicon.ico --noconsole main.py
来源:52pj
签名:这个人很懒,什么也没有留下!
最新回复 (0)