Windows 上的图形化批量文件处理合集:把 17 个常用小工具塞进同一个窗口,左侧纵向菜单切换即可使用。 全部操作都在本地完成,不联网、不上传任何文件。
设计原则:只做整理,不做破坏。 所有移动 / 重命名 / 覆盖类操作都带防覆盖策略(同名跳过或自动改名、两阶段重命名、先预览后执行), 宁可跳过也绝不误删、误覆盖。
| 编号 | 功能 | 做什么 |
|---|---|---|
| ① | 文件分组 | 按数量(每组 N 个)或按年月把文件分到子文件夹 |
| ② | 移动到根目录 | 把所有子目录里的文件提升到根目录 |
| ③ | 删除空文件夹 | 循环清理嵌套的空目录 |
| ④ | 实况图分组 | 识别安卓实况图(JPEG 内嵌视频),分出实况图 / 静态图,可提取 mp4 |
| ⑤ | 文件名添加路径 | 把目录层级写进文件名(根目录-子目录-原名) |
| ⑥ | 序号重命名 | 批量改成 001/002… 或 001-原名,支持拖放、自然排序 |
| ⑦ | 视频常用压制 | FFmpeg 批量压制:AV1 / H.265 自由选,硬件编码器自动选择(NVENC → QSV → 软件),内嵌字幕硬烧,源文件自动归档 |
| ⑧ | 视频横竖屏 | 读视频头判断横屏 / 竖屏并分文件夹,速度极快 |
| ⑨ | 文件名删除 | 按位置删除文件名中的字符(从前 / 从后、第几位、删几个) |
| ⑩ | 图片生成MD | 把图片整理成 Markdown(复制图片 + 生成索引),支持增量更新 |
| ⑪ | TXT转图片 | 把 TXT 批量渲染成 PNG(中文自动换行) |
| ⑫ | TXT合并 | 按后缀把多个文件合并成一个,保留来源标注 |
| ⑬ | TXT重命名 | 用 TXT 第一行的文字作为文件名 |
| ⑭ | WebP转JPG | WebP 批量转 JPEG,可转完删除原文件 |
| ⑮ | 加密包分类 | 扫描压缩包,把加密的挑出来移到指定文件夹 |
| ⑯ | 图片压缩 | mozjpeg Huffman 无损优化 / libjpeg-turbo 重压缩,看体积省多少 |
| ⑰ | ReSoBackup备份 | Reed-Solomon 纠删码分片备份,任意 K 份即可恢复,可选 AES-256-GCM |
-
系统:Windows 10 / 11(64 位)。拖放、路径长度等逻辑都按 Windows 行为实现。
-
直接跑 exe:无需安装任何东西,双击
文件工具箱.exe即可。 -
从源码跑:Python 3.10 及以上,且必须带
tkinter。 建议用 python.org 的官方安装包(安装时勾选tcl/tk and IDLE)。 部分"精简版 / 应用商店版 / 托管版"的pythonw.exe不带 tkinter,会导致启动即退出。 -
第三方依赖:按需安装(见 依赖与降级策略):
pip install pillow chardet pycryptodome pip install pyzipper rarfile py7zr
-
FFmpeg(仅 ⑦ 视频常用压制需要):外部程序,不内置在 exe 里。没装只影响 ⑦, 其它 16 个工具照常使用。放置位置见 ⑦ 视频常用压制。
- 双击
文件工具箱.exe(单文件、无控制台窗口)。 - 左侧点选功能,填好参数,点右下角按钮执行。
- 窗口大小 / 位置 / 菜单栏宽度会自动记住,存在 exe 同目录的
toolbox_window.json。
首次启动单文件 exe 需要解压到临时目录,可能要等几秒;杀毒软件偶尔会误报, 因为 PyInstaller 单文件包的行为特征比较像"自解压程序"。源码就在仓库里,可自行打包。
:: 双击 启动工具箱.bat,或者:
python 文件工具箱.py启动工具箱.bat 会优先找一个带 tkinter 的 pythonw.exe(无控制台窗口)来启动,
找不到时回退到命令行 python 并把报错显示出来,方便排查。
见 打包成 exe。
- 左侧纵向菜单:17 个功能,窗口高度不够时可用滚轮上下滚动(内容超出才出现滚动条, 滚动范围被严格限制,不会滚出空白)。
- 菜单栏宽度可调:拖动菜单右侧的细分隔条即可;双击分隔条恢复默认宽度(默认 210px,范围 160–360px)。
- 参数区:路径行带"浏览…",后缀 / 格式行支持直接输入自定义值(如
.webp .heic、jpg png)。 - 日志区:所有操作都会在下方日志里逐条记录,执行中按钮会禁用,避免重复点击。
- 先预览后执行:⑤⑥⑨ 三个重命名类工具都是先"预览重命名结果",确认无误再"执行重命名"。
- 拖放:⑥⑦⑧⑨⑯⑰ 等页面支持把文件 / 文件夹直接拖进列表(自己实现的 Windows 拖放,
基于
ctypes+SetWindowSubclass,不依赖第三方库,也没有 64 位回调截断导致崩溃的问题)。
把目录里的文件按规则搬进子文件夹:源目录/前缀_1/、源目录/前缀_2/……
- 分组方式
- 按数量分组:每 N 个文件一组。
- 文件后缀下拉:
.jpg/.gif/.txt/.mp4/*,也可直接输入任意后缀(如.psd)。 *= 按图片格式分组:只会捞取「图片格式」里列出的扩展名(默认jpg jpeg png gif bmp tiff webp, 可自行修改),不会把目录里所有文件都笼统分掉。- 每组数量可自定义(默认 1500)。
- 文件夹前缀默认随后缀自动变化(
*用Group),可手动改。
- 文件后缀下拉:
- 按年月分组:按文件修改时间归入
年-月文件夹(如2025-12)。 这一模式用「图片格式」输入框筛选,留空或*表示所有格式。
- 按数量分组:每 N 个文件一组。
- 只处理当前文件夹,不进入子目录。
- 同名文件跳过,不覆盖。
把各层子目录里的文件全部提升到根目录。
- 默认递归所有层级,取消勾选只处理一级子目录。
- 默认遇到同名文件跳过不移动;勾选「同名重命名移动」后会自动加后缀,两种模式都不会覆盖已有文件。
- 可勾选「移动完成后删除空的子文件夹」。
循环删除目标目录下的所有空文件夹(含嵌套空目录),根目录本身保留。 只要目录里还有文件或其子目录里还有内容,就不会被删。
识别安卓实况图(JPEG 里内嵌了一段 MP4),把图片分类:
- 支持
.jpg/.jpeg/.heic/.heif/.png,只处理当前文件夹,不进入子目录。 - 实况图 →
LivePhotos/,静态图 →StaticPhotos/(两个移动开关可分别关闭,关闭则保持原位)。 - 可选「提取实况图视频到
LivePhotos/videos」,导出的 mp4 可直接播放。
把文件的目录层级写进文件名:根目录-子目录-原名.jpg。
- 可递归子目录;可勾选「带上输入文件夹名称」决定是否包含最外层目录名。
- 必须先预览再执行;预览是左右两栏对照(原文件名 / 重命名后),确认无误再执行, 执行前还会再弹一次确认框。
- 重命名后完整路径超过 255 字符的文件会被跳过,并在页面下方单独列出(Windows 无法处理超长路径)。
把文件或文件夹批量改成序号名。
- 输入:拖入列表,或「添加文件 / 添加文件夹」;添加文件夹时可选择是否遍历子目录。
- 两种模式:全部重命名为序号(
001.jpg)、原文件名前加序号(001-原名.jpg)。 - 序号位数 1–10(默认按数量自动够用)、起始序号可任意正整数。
- 勾选「仅处理文件夹」时忽略文件,只重命名拖入文件夹内的子文件夹。
- 排序用数值化自然排序:
9.jpg排在10.jpg前面,不会出现字典序的错位。 - 执行采用两阶段重命名(先改成临时名,再改成目标名),换名过程中不会互相覆盖。
- 同样支持先预览再执行。
调用外部 FFmpeg 批量压制视频,硬件编码器自动选择,内嵌字幕可硬烧,处理完自动归档源文件。
本页不依赖 Python 第三方库,只依赖 ffmpeg.exe + ffprobe.exe。
- 打开本页时才检测(不拖慢程序启动):按「手动指定 → 程序目录 →
程序目录\bin\ffmpeg\→ 系统 PATH」的顺序找ffmpeg.exe,同目录下要有ffprobe.exe。 - 找不到会弹窗提示(本页只提示一次),日志里也会写明补救方法。点「浏览…」选中
ffmpeg.exe即可,路径会记到 exe 同目录的ffmpeg_config.json,下次自动使用。 - 顶栏会显示检测到的版本号;点「重新检测」可重新定位并重新探测编码器。
推荐 gyan.dev 的 release-full 构建(含 NVENC / QSV /
libass / libx265 / libsvtav1)。解压后把 bin 里的两个 exe 放到程序目录即可。
对 AV1 与 H.265 分别探测,顺序都是 NVENC → QSV → 软件:
| 编码格式 | 首选 | 次选 | 兜底 |
|---|---|---|---|
| AV1 | av1_nvenc |
av1_qsv |
libsvtav1 |
| H.265 | hevc_nvenc |
hevc_qsv |
libx265 |
探测不是只看 ffmpeg -encoders 列表(有列表 ≠ 有显卡),而是真跑一次 0.2 秒黑帧,
能成功初始化才算可用。所以「有 NVENC 但显卡不支持 AV1」这种常见情况会正确回退到 QSV 或软件,
页面上会直接写明当前用的是哪条链路,例如:
编码器:AV1 → 软件(libsvtav1);H.265 (HEVC) → QSV(hevc_qsv)
没有任何硬件编码器时会明确提示,不会悄悄用 CPU 压:
- 编码器那一行会变成橙色,日志里也会写明「AV1 只能用 CPU 软件编码(libsvtav1),速度慢很多」。
- 如果本机 AV1 没有硬件编码(大多数 Intel 核显、GTX 16 系、RTX 20 系都不支持 AV1 编码) 而 H.265 有硬件编码,打开本页时会自动把「编码格式」切到 H.265, 避免默认的 640p 直接掉进慢速 CPU 编码;想用 AV1 软件编码(体积更小)可以手动切回来。
- 硬件编码是否可用取决于显卡本身,不是程序判断错误:
例如
av1_qsv在只支持 H.264/H.265 的核显上会报Current codec type is unsupported。
编码格式在三种模式下都能自由选 AV1 或 H.265(可以「640p 的 AV1」「640p 的 H.265」 「高清的 AV1」「高清的 H.265」)。质量与 preset 不用自己填,按「模式 + 编码格式」自动套用:
| 模式 | 分辨率 | 质量 | preset |
|---|---|---|---|
| 640p | 最长边限制到 640(不放大),横屏限宽 / 竖屏限高 | AV1:QSV 34 / NVENC 36;H.265:QSV 24 / NVENC 29 | 随编码器默认(NVENC p1·p4 / QSV medium / SVT 8) |
| 高清 | 保持原始分辨率 | 统一 crf/cq 18 | 随编码器默认 |
| 自定义 | 保持原始分辨率 | 0–63 自己填 | 随编码器给出可选列表 |
参数体系与 ShanaEncoder 的常用预设对齐:
AV1 (NVENC) -preset p1 -cq 36
AV1 (QSV) -preset medium -global_quality 34
H.265 (NVENC) -preset p4 -cq 29
H.265 (QSV) -preset medium -global_quality 24
- 启动时会按实际探测到的编码器(QSV 还是 NVENC)自动填好质量与 preset; 640p / 高清两种模式下这两个框置灰,切到「自定义」才可编辑,避免参数和模式对不上。
- NVENC 走
-rc vbr -cq N -b:v 0(纯质量模式),QSV 走-global_quality N, 软件编码走-crf N。 - 10bit / HDR 源自动改用
main10+p010le,普通 8bit 源用main+yuv420p; HDR 还会把源视频的color_primaries / color_trc / colorspace原样带到输出,避免发灰。
-
导入时自动探测内嵌字幕轨,列表「字幕」列显示条数与语言(如
1条 chi)。 -
勾选「硬烧内嵌字幕」后,自动挑一条:优先中文(
zh/chi/zho或标题含"中文/简体/繁体/中字") → 默认轨 → 第一条。文字字幕会先转成 ASS 再烧。 -
样式复刻 ShanaEncoder,强制 ASS 样式:
FontName=Microsoft YaHei, FontSize=15, Outline=2, Shadow=2, MarginL=10, MarginR=10, MarginV=20, Alignment=2(居中底部) -
滤镜顺序:「字幕 → 旋转 → 缩放」,与 ShanaEncoder 的预设一致 (带旋转元数据的手机竖拍视频,字幕会跟着画面一起转,属于该预设本身的特性)。
-
位图字幕(PGS / VobSub / DVB)无法用 libass 渲染,会跳过并写进日志,不影响视频压制。
- 输出命名:
原文件名.crf<质量值>.mp4(如原文件名.crf36.mp4;自定义改过质量就跟着变)。 同名已存在时自动加_1、_2,绝不覆盖。源文件名本身带.crfNN后缀时不会再叠加 (x.crf36.mp4压出来是x.crf24.mp4,不会变成x.crf36.crf24.mp4)。 - 归档:压制成功把源文件移到
success/,失败移到error/,同名自动加序号。 归档目录在「输出目录」(留空 = 源文件所在目录)下。失败时半成品会被删掉。 - 不会重复压、也不会套娃:添加文件夹时会跳过
success/、error/子目录, 以及xxx.crfNN.mp4这类本程序压出来的成品;已经在success/或error/里的源文件 不会再被往深层搬(不会出现success/success/error/error)。 每批结束后,已归档的条目会自动从列表移除,下次点「开始」不会去压已经不存在的文件; 开始前也会再检查一遍,文件真被移走了会提示并跳过。 - 并发:默认 4 个文件同时压,可调 1–16。视频信息探测也走线程池(4 线程), 导入几百个文件时 GUI 不会卡。
- 进度:按钮右边有总进度条和「已完成 3/8 · 成功 2 · 失败 1」这样的文字, 列表「状态」列同时显示每个文件的「压制中 45%」;整体进度按已完成文件数 + 正在压制的 百分比估算,看得到现在压到第几个。
- 想看单个文件的进度和它执行的命令:勾选「显示 ffmpeg 窗口」,每个任务会弹出一个
独立的控制台窗口 —— 窗口标题是输出文件名,正文先打印实际执行的完整 ffmpeg 命令
(可以直接选中复制,拿去手动跑),下面是 ffmpeg 原生的
frame / fps / speed / time进度。 同一条命令也会写进运行日志(以「命令:」开头)。不勾选则完全静默,报错汇总到日志。 出错时窗口会停 10 秒并显示 ffmpeg 的返回码,同时 ffmpeg 的报错行也会写进运行日志。 - 点「停止」会结束正在跑的 ffmpeg 进程(连它所在的控制台一起结束),已完成的文件不受影响。
- 音频:源音轨是 AAC / MP3 / AC3 / E-AC3 / ALAC 时直接
copy,否则统一转 AAC 192k。
识别指定文件夹里的视频是横屏还是竖屏,分别移动到「横屏」「竖屏」子文件夹。
- 只处理当前文件夹,不进入子目录。
- 只读取视频容器头信息判断分辨率,不解码画面,所以速度极快、不改画质。
- 视频格式可自定义(默认
mp4 m4v mov mkv webm ts mts m2ts flv avi wmv asf …)。 - 识别线程数可调(默认 8)。
- 无法识别的视频可勾选移到「未知」文件夹,否则保持原位。
按位置删除文件名中的字符:
- 参数:从第几位开始(从 1 数)、删除几个字、从前还是从后。
- 例:从第 1 位开始删 2 个字,
01_照片.jpg→照片.jpg。 - 文件只删主文件名,不动扩展名;删完为空的自动跳过。
- 支持拖放、仅处理文件夹、先预览后执行(与 ⑥ 一致)。
把一堆图片整理成一个 Markdown 索引,图片本体复制进 输出文件夹/appdata/Image/。
新建模式(还没有同名 md 时)
-
图片副本放在
源目录/输出文件夹/appdata/Image/(输出文件夹名默认记录,可改), 文件名形如源目录名_子目录名_原文件名_6位随机串.jpg(随机后缀保证绝不覆盖历史文件)。 -
生成
源目录名.md(同样在输出文件夹里),每张图三段式: > 文件:01.jpg
-
选项:递归遍历子目录、md 添加文件夹名称(
## 子目录小节)、md 添加原图名称(> 文件:…那行)。 -
图片按文件名自然排序(
9在10前面)写入,与更新模式的插入假设一致。
更新模式(已存在同名 md 时自动启用)
只做增量,不动任何已有内容:
- 扫描源目录,与 md 里已引用的图片比对,找出新增的图片(判断依据是「子目录前缀 + 原文件名」, 所以不同子目录的同名图不会互相误判;地址被手工改过的,退回按文件名判断)。
- 只把新增的图片复制到
appdata/Image/(新文件名、新随机后缀,旧文件不受影响)。 - 按文件名自然排序确定插入位置:
- 找到「排序后下一张已引用的图片」,把新块插到那张图的文本上方;
- 如果后面连续几张都还没被引用,就继续往下找;
- 一直找到底都没有,就作为该小节的最后一张追加。
- 新出现的子目录会在文末追加新的
## 子目录小节;md 原本是平铺结构(没有##)时不造标题, 直接按全局文件名顺序插入。
举例:md 里已有 01 / 02 / 04,新增 03,结果就是插入到 04 的文本上方。
其他行为:
- 没有新增图片时,md 一字不改,也不会复制任何文件(日志会说明"没有新增")。
- 你手写的备注、手工调整过的段落顺序都会原样保留。
- 保留原文件的换行符(CRLF / LF)与 BOM,避免整篇 diff。
- 注意:判断依据是"源目录有、md 里没引用"。所以如果你手工删掉了某张图的引用块, 而源目录里那张图还在,下次运行会把它当作未引用的新图再补回去。
把 TXT 文件批量渲染为 PNG(中文自动换行)。
- 参数:TXT 目录、输出目录、字体文件(
ttf/ttc)、字号、每行字数、并发线程数。 - 需要
pillow。
把指定后缀的文件合并成一个大文件。
- 参数:目标文件夹、目标后缀(下拉
.txt/.srt/.md/.log,也可直接输入)、是否递归子目录(默认只合并当前层)。 - 每个文件前会带上原文件名与完整路径,并用
=分隔线隔开,方便溯源。 - 输出
全部合并结果<后缀>(默认全部合并结果.txt);若已存在则自动加_1、_2,不覆盖。 - 读取文件时会自动猜编码:优先
chardet检测结果,然后依次尝试 UTF-8 / GBK / GB2312 / Big5 等。
用 TXT 第一行的文字作为新文件名。
- 自动清理 Windows 非法字符(
\ / : * ? " < > |),首行为空的文件跳过。 - 重名自动去重(加序号),不会覆盖已有文件。
WebP 批量转 JPEG。
- 参数:源目录、输出目录、JPG 质量(默认 100)、是否「转换成功后删除原 webp」(默认勾选)。
- 需要
pillow。
扫描目录里的压缩包,把加密的那些移动到指定文件夹(例如集中到一个「加密」目录里再处理)。
- 压缩包后缀默认
.zip .rar .7z,可自定义。 - 目标文件夹名默认
加密(在扫描目录下创建),可改。 - 可递归扫描子文件夹。
.zip用标准库即可识别;.rar/.7z需要rarfile/py7zr。
批量压缩 JPEG / PNG / WebP / TIFF / BMP,支持拖入文件或文件夹。
- 保存路径
覆盖原图(不可逆,页面有明确提示,请先备份);原路径重命名;保存到指定路径。
- 压缩设置:是否启用压缩、是否保留 Exif、编码器
mozjpeg(默认,自带 Huffman 优化,体积更小) 或libjpeg-turbo(Pillow 自带)。 - 结果格式:保持原格式 / 统一为 JPG(PNG/WebP/TIFF/BMP 按质量重压缩为 JPEG)。
- 图片质量:滑杆调节(默认 96)。
- 多线程并行压缩(默认勾选,最多 8 个线程);列表里展示每张图的压缩前后体积与节省比例。
- 压缩失败收集:可把失败文件复制到指定目录,方便单独重试。
- 只读属性的源文件会跳过(无法覆盖写入);动图(多帧 GIF / 动画 WebP)会跳过,避免被压成单帧。
- 选项会记忆到 exe 同目录的
compressor_config.json。
Reed-Solomon 纠删码备份:把文件切成 N 份分片,任意 K 份即可恢复,可分散存到多个位置(U 盘、网盘、异地)。
- 备份:源文件、分片数(3–128,默认 8)、恢复阈值(1–分片数,默认 5; 冗余 = 分片数 − 阈值)、输出目录(留空 = 源文件所在目录)。
- 加密(可选):AES-256-GCM,密钥由
scrypt派生(可同时加密文件名)。 - 恢复:任选一个分片或
.rsmeta,只在所选文件所在目录查找同组分片(按 batch_id 分组,不会混入同名旧分片); 加密备份必须填密码。输出目录留空时,还原到分片所在目录下的rebuild文件夹。 - 不覆盖旧文件:恢复出的文件与已有文件同名时自动加
_1、_2后缀。 - 分片不足提示:会列出已找到/缺少的分片序号、需要几份、实际几份以及搜索的目录,方便补齐。
- 错误提示:未填密码、密码错误、分片损坏、分片与元数据不匹配都会给出中文原因和处理建议。
- 分片自带元数据副本:备份时会把
.rsmeta的紧凑副本写到每个分片尾部(分片数据之后,带 SHA-256 校验), 所以删除/丢失.rsmeta后,选任意一个新分片即可完整恢复,包括加密备份、原始文件名和精确大小。 - 旧备份的分片没有内嵌元数据:仍可用 31 字节分片头恢复未加密文件,但原始大小未知
(会自动去掉尾部 0 填充并在日志提示),加密备份必须找回
.rsmeta。 - 31 字节分片头与 Go 版 ReSoBackup 保持一致;尾部元数据副本位于
data_size之后, 按分片头长度读取数据的旧工具不会把它算进分片数据。
| 场景 | 策略 |
|---|---|
| 分组 / 移动时目标已存在同名文件 | 跳过,或(可选)自动改名,绝不覆盖 |
| 重命名(⑤⑥⑨) | 两阶段重命名,先临时名后目标名,批量过程不会互相覆盖;执行前必须预览 |
复制图片到 appdata/Image |
文件名带 6 位随机串,拷贝前检查是否已存在 |
| 生成 md / 合并 txt | 已存在时自动加 _1、_2 |
| 生成 md(更新模式) | 只插入新增块,已有行原样保留;无新增时文件不改动 |
| 超长路径(> 255 字符) | 跳过并单独列出,不冒险写入 |
| 只读文件 / 动图 | 压缩时跳过并记录原因 |
| 覆盖原图(⑯) | 页面明确标注"执行覆盖操作不可逆,请确认已备份";不想覆盖可改用「原路径重命名」或「保存到指定路径」 |
| 压制输出(⑦) | 输出名带 crf 质量值,同名自动加序号;源文件只在成功后移入 success/,失败移入 error/,失败半成品会删除 |
fileTools/
├─ 文件工具箱.py 入口脚本(打包时也是它)
├─ 启动工具箱.bat 源码启动(优先找带 tkinter 的 pythonw)
├─ 打包.bat 一键 PyInstaller 打包成单文件 exe
├─ bin/
│ └─ mozjpeg/ ⑯ 图片压缩用的 mozjpeg 官方构建(cjpeg / jpegtran 等)
└─ toolbox/ 源码包
├─ main.py 主窗口:左侧菜单、页面切换、窗口几何记忆
├─ common.py 通用基础设施:日志面板、后台任务、路径行、拖放支持、自然排序
├─ tab_grouping.py ① 文件分组 ② 移动到根目录 ③ 删除空文件夹
├─ tab_live.py ④ 实况图分组
├─ tab_rename.py ⑤ 文件名添加路径 ⑥ 序号重命名 ⑨ 文件名删除
├─ tab_video.py ⑧ 视频横竖屏
├─ tab_docs.py ⑩ 图片生成MD ⑪ TXT转图片 ⑫ TXT合并 ⑬ TXT重命名
├─ tab_media.py ⑭ WebP转JPG ⑮ 加密包分类
├─ tab_compress.py ⑯ 图片压缩
├─ tab_rsbackup.py ⑰ ReSoBackup备份
└─ tab_encode.py ⑦ 视频常用压制(调用外部 FFmpeg)
运行期生成的文件(都不进版本库):
toolbox_window.json:窗口大小 / 位置 / 菜单栏宽度,删掉即恢复默认。compressor_config.json:⑯ 图片压缩的选项记忆。ffmpeg_config.json:⑦ 手动指定的 ffmpeg 路径(点「浏览…」后写入)。
双击 打包.bat,或手动执行:
python -m PyInstaller --onefile --windowed --noconfirm --clean ^
--name 文件工具箱 ^
--add-data "bin\mozjpeg;bin/mozjpeg" ^
--hidden-import PIL.Image --hidden-import PIL.ImageDraw --hidden-import PIL.ImageFont ^
--hidden-import Crypto.Cipher.AES --hidden-import Crypto.Util._raw_api ^
文件工具箱.py说明:
--onefile --windowed:单文件、不带黑色控制台窗口。--add-data bin\mozjpeg:把 mozjpeg 二进制一起打进去(打包后程序从sys._MEIPASS找它们); 如果没有这个目录,⑯ 的默认编码器会提示缺失并自动回退libjpeg-turbo。--hidden-import:Pillow / PyCryptodome 的部分子模块是动态导入的,不声明会被裁掉。- 打包脚本会把产物复制到根目录并清理
.pybuild/;杀毒软件可能瞬时占用旧 exe,脚本会重试 5 次。 - FFmpeg 不打进 exe:它体积大(100 MB 以上)且需要与显卡驱动匹配,用外置方式检测更灵活。
分发时只需把
ffmpeg.exe/ffprobe.exe放在 exe 同目录(或bin\ffmpeg\)。
| 依赖 | 用在 | 缺失时 |
|---|---|---|
tkinter |
全部界面 | 程序无法启动(系统 Python 请勾选 tcl/tk) |
pillow |
⑪⑭⑯ | 对应页面运行时报错提示安装 |
chardet |
⑪⑫⑬ 读取非 UTF-8 文本 | 依次尝试 UTF-8 / GBK / GB2312 / Big5 等编码 |
pycryptodome |
⑰ ReSoBackup 加密 | 只能做不加密的备份/恢复 |
pyzipper / rarfile / py7zr |
⑮ 识别加密包 | .zip 用标准库照样能识别,.rar / .7z 需要它们 |
bin/mozjpeg |
⑯ 默认编码器 | 自动回退 Pillow 的 libjpeg-turbo,压缩率略低 |
ffmpeg / ffprobe(外部程序) |
⑦ 视频常用压制 | 打开 ⑦ 时弹窗提示,其它 16 个工具不受影响 |
Q:双击 启动工具箱.bat 闪退 / 没有任何窗口?
A:多半是 Python 没有 tkinter。用命令行跑 python 文件工具箱.py 看具体报错;
建议安装 python.org 官方版并勾选 tcl/tk and IDLE。
Q:拖文件进列表没反应? A:先确认程序不是"以管理员身份运行"——Windows 的 UIPI 限制下,普通权限的资源管理器无法向 管理员窗口拖放。此时请用页面上的「添加文件 / 添加文件夹」按钮。
Q:图片压缩提示 mozjpeg 缺失?
A:bin/mozjpeg 没放到程序目录(exe 版打包时会内置)。程序会自动回退 libjpeg-turbo,
功能不受影响,只是压缩率略低。
Q:⑩ 为什么把我删掉的图又加回来了? A:更新模式的判断依据是"源目录有、md 里没引用"。手工删掉引用块≠告诉程序"这张图不要", 只要源图还在,下次运行就会补回。若确实不想要,请把源图移走或改名。
Q:toolbox_window.json / compressor_config.json 是什么?
A:窗口状态与压缩选项的记忆文件,随意删除,下次启动会自动重建默认值。
Q:覆盖原图后能撤销吗? A:不能。⑯ 的「覆盖原图」是不可逆操作,页面也有提示;批量处理前建议先备份或先用 「保存到指定路径」验证效果。
Q:⑦ 视频压制提示"未找到 FFmpeg"?
A:把 ffmpeg.exe、ffprobe.exe 放到程序目录(或 程序目录\bin\ffmpeg\),
或者把 ffmpeg 加进 PATH,再或者在本页点「浏览…」手动选中 ffmpeg.exe。
检测只在打开本页时进行,所以在其它页面不会被打扰。
Q:⑦ 显示"AV1 → 软件(libsvtav1)",是不是没启用硬件加速?
A:这台机器的显卡不支持 AV1 硬件编码(GTX 16 系、RTX 20 系、大多数 Intel 核显都不支持
AV1 编码,QSV 会报 Current codec type is unsupported)。程序会在打开本页时给出橙色提示,
并且在 H.265 有硬件编码的情况下默认把编码格式切到 H.265,避免误用 CPU 慢慢压。
想继续用 AV1 软件编码(体积更小)就在下拉框里手动切回来。
Q:⑦ 弹出的黑窗口是什么? A:勾选「显示 ffmpeg 窗口」后,每个文件会弹一个独立的控制台:第一行是实际执行的 ffmpeg 命令,下面是 ffmpeg 自己的进度(frame/fps/speed/time)。不想看窗口可以取消勾选, 程序内部仍会解析进度并显示在列表里。出错时窗口停留 10 秒,报错行同时会写进运行日志。
Q:⑦ 整批都报 Error opening input: No such file or directory?
A:这是列表里的路径失效了 —— 一般是上一次压制已经把源文件归档进 success/,又用同一份
列表点了第二次「开始」。现在每批结束后已归档的条目会自动从列表移除,开始前也会再校验一次,
正常不会再出现。如果以前留下了 success/success/error/error 这种套娃目录,
把里面的文件手动整理回原目录即可,新版本不会再往深处搬。
Q:⑦ 竖拍视频硬烧字幕后字幕歪了?
A:这类视频带旋转元数据,按 ShanaEncoder 的预设「字幕 → 旋转」烧录时字幕会跟着转 90°。
想要正的字幕可以把旋转交给 ffmpeg 自动处理(不加 -display_rotation 0),或改用外挂字幕。
Q:ffmpeg_config.json 是什么?
A:⑦ 记住的手动 ffmpeg 路径,删掉即回到"自动查找"。
- 新增 ⑦ 视频常用压制:调用 FFmpeg 批量压制,AV1 / H.265 自由选,硬件编码器按
NVENC → QSV → 软件 自动选择(真跑一次黑帧验证,不只看编码器列表);
640p / 高清 crf18 / 自定义三种模式,质量与 preset 按「模式 + 编码格式」自动套用
(QSV:AV1 34 / H.265 24;NVENC:AV1 36 / H.265 29);
内嵌字幕硬烧(复刻 ShanaEncoder 样式与滤镜顺序);
成功归档
success/、失败归档error/;并发默认 4,视频信息多线程探测不卡界面。 - ⑦ 增加总进度条与「已完成 x/y」文字,列表状态列显示单文件百分比; 可选「显示 ffmpeg 窗口」看 ffmpeg 原生统计。该工具移到菜单第 7 位,其后编号顺延。
- ⑦ 勾选「显示 ffmpeg 窗口」时,弹出的控制台会先打印完整 ffmpeg 命令(同时写进日志), 再显示 ffmpeg 自己的进度;窗口标题是输出文件名,失败时窗口停留 10 秒方便看报错。
- ⑦ 编码器探测补充提示:本机 AV1 只有软件编码、H.265 有硬件时,打开页面会自动把编码格式 切到 H.265(避免默认 640p 掉进 CPU 编码),编码器那一行变橙色并写日志说明。
- ⑦ 修复「显示 ffmpeg 窗口」一开就整批失败(
ffmpeg 返回 1/4294967294): 改成把命令行直接交给cmd /s /c(不再落地 UTF-8 批处理,中文路径不会被按 GBK 解码成乱码), 并且窗口模式不再给子进程传stdin(传了会让 exe 把无效句柄继承给 ffmpeg,写不了状态就退出)。 出错时窗口停留 10 秒并显示返回码,报错行也会同步到运行日志。返回码改为可读的负数。 修复窗口里成功任务也误报「ffmpeg 出错,返回码 0」(set RC=!ERRORLEVEL!把空格吃进了变量, 改成set "RC=!ERRORLEVEL!");添加的素材若在 success/error 归档目录里,会明确提示原地处理。 - ⑦ 修复归档套娃与重复压制:添加文件夹时跳过
success/、error/与xxx.crfNN.mp4成品; 已在归档目录里的源文件不再往深层搬;输出名不再叠加.crfNN;每批结束自动移除已归档条目, 开始前校验文件是否存在(失效条目直接跳过,不再整批No such file)。 - FFmpeg 只在打开 ⑦ 页时检测,找不到弹窗提示,可手动指定路径并记住。
- ⑩ 图片生成MD 新增更新模式:已有同名 md 时只追加新增图片,按文件名顺序插入到 「排序后下一张已引用图片」的文本上方,已有内容(含手写备注)完全不动;无新增时文件不变。
- ⑩ 新建 md 改为按文件名自然排序(
9在10前面),与更新模式的插入顺序一致。 - 左侧菜单滚轮越界修复:内容不足一屏时不再滚动、不再滚出空白;内容超出时才显示滚动条, 且滚动范围严格限制在内容高度内。
- 自然排序函数统一到
common.natural_key,⑤⑥⑨ 与 ⑩ 共用同一套排序规则。
-
每个功能页是一个
build_xxx_tab(parent)函数,parent是一个ttk.Frame,页面内控件用grid布局。 -
toolbox/main.py里的builders列表决定菜单顺序与页面构建:builders = [ ("① 文件分组", build_group_tab), ("② 移动到根目录", build_flatten_tab), # ... ]
-
需要拿到主窗口的页面(拖放、全局状态)会被多传一个
app参数,它们在if builder in (build_seq_rename_tab, build_trim_tab, build_video_tab, build_compress_tab, build_rsbackup_tab, build_encode_tab)这一行里登记;拖放通过app.register_drop_handler(parent, add_paths)注册。 -
想「打开页面时才做某件事」(例如 ⑦ 的 ffmpeg 检测)的页面,用
app.register_show_handler(parent, 回调)注册,切换页面时会被调用。 -
耗时操作统一走
common.run_task(button, log, work, on_done=...): 后台线程执行work(),日志通过队列回到主线程,执行期间按钮置灰,异常会写进日志并弹窗。
- 在
toolbox/tab_xxx.py里写build_xxx_tab(parent),用common里的make_path_row/make_check/make_spin_row/make_log_panel/make_start_button拼装界面,耗时逻辑写进普通函数(后台线程里不要直接操作 Tk 控件,统一用log())。 - 在
main.py的builders列表里加一项("⑱ 新工具", build_xxx_tab)。 - 若需要拖放,把
build_xxx_tab加进上面那个if builder in (...)元组,并在页面里调用app.register_drop_handler(parent, 你的回调)。 python 文件工具箱.py自测,再打包.bat。
- 注释与界面文案用中文;文件名、变量名用英文。
- 任何写文件的地方都要考虑"目标已存在":跳过或改名,不要直接覆盖。
- 所有用户可见的进度、跳过原因、失败原因都写进日志,不要只弹一个"完成"。
- mozjpeg:⑯ 图片压缩的 JPEG 编码器与无损优化工具。
- ReSoBackup:⑰ 的 Reed-Solomon 分片格式参考实现(原项目为 Go 版,此处为 Python 重写)。
- FFmpeg:⑦ 视频压制的编码 / 探测引擎(以外部程序方式调用)。
- ShanaEncoder:⑦ 的压制参数与字幕样式参考。
- Pillow:图片读写与缩放。
- PyCryptodome:AES-256-GCM 加密。
本仓库暂未指定开源许可证;如需在其它项目中复用,请先联系作者。