Skip to content
zero6363Public

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

17 Commits

Folders and files

Repository files navigation

文件工具箱 · 多功能合集

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(推荐给普通使用)

  1. 双击 文件工具箱.exe(单文件、无控制台窗口)。
  2. 左侧点选功能,填好参数,点右下角按钮执行。
  3. 窗口大小 / 位置 / 菜单栏宽度会自动记住,存在 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)。 这一模式用「图片格式」输入框筛选,留空或 * 表示所有格式。
  • 只处理当前文件夹,不进入子目录。
  • 同名文件跳过,不覆盖。

② 移动到根目录

把各层子目录里的文件全部提升到根目录。

  • 默认递归所有层级,取消勾选只处理一级子目录。
  • 默认遇到同名文件跳过不移动;勾选「同名重命名移动」后会自动加后缀,两种模式都不会覆盖已有文件。
  • 可勾选「移动完成后删除空的子文件夹」。

③ 删除空文件夹

循环删除目标目录下的所有空文件夹(含嵌套空目录),根目录本身保留。 只要目录里还有文件或其子目录里还有内容,就不会被删。

④ 实况图分组

识别安卓实况图(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。

1. FFmpeg 环境

  • 打开本页时才检测(不拖慢程序启动):按「手动指定 → 程序目录 → 程序目录\bin\ffmpeg\ → 系统 PATH」的顺序找 ffmpeg.exe,同目录下要有 ffprobe.exe。
  • 找不到会弹窗提示(本页只提示一次),日志里也会写明补救方法。点「浏览…」选中 ffmpeg.exe 即可,路径会记到 exe 同目录的 ffmpeg_config.json,下次自动使用。
  • 顶栏会显示检测到的版本号;点「重新检测」可重新定位并重新探测编码器。

推荐 gyan.dev 的 release-full 构建(含 NVENC / QSV / libass / libx265 / libsvtav1)。解压后把 bin 里的两个 exe 放到程序目录即可。

2. 编码器自动探测

对 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。

3. 三种模式 + 自由编码格式

编码格式在三种模式下都能自由选 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 原样带到输出,避免发灰。

4. 字幕硬烧

  • 导入时自动探测内嵌字幕轨,列表「字幕」列显示条数与语言(如 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 渲染,会跳过并写进日志,不影响视频压制。

5. 输出、归档与并发

  • 输出命名:原文件名.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。
  • 文件只删主文件名,不动扩展名;删完为空的自动跳过。
  • 支持拖放、仅处理文件夹、先预览后执行(与 ⑥ 一致)。

⑩ 图片生成MD

把一堆图片整理成一个 Markdown 索引,图片本体复制进 输出文件夹/appdata/Image/。

新建模式(还没有同名 md 时)

  • 图片副本放在 源目录/输出文件夹/appdata/Image/(输出文件夹名默认 记录,可改), 文件名形如 源目录名_子目录名_原文件名_6位随机串.jpg(随机后缀保证绝不覆盖历史文件)。

  • 生成 源目录名.md(同样在输出文件夹里),每张图三段式:

    ![01.jpg](appdata/Image/旅行_01_Txc3Kd.jpg)
    > 文件:01.jpg
  • 选项:递归遍历子目录、md 添加文件夹名称(## 子目录 小节)、md 添加原图名称(> 文件:… 那行)。

  • 图片按文件名自然排序(9 在 10 前面)写入,与更新模式的插入假设一致。

更新模式(已存在同名 md 时自动启用)

只做增量,不动任何已有内容:

  1. 扫描源目录,与 md 里已引用的图片比对,找出新增的图片(判断依据是「子目录前缀 + 原文件名」, 所以不同子目录的同名图不会互相误判;地址被手工改过的,退回按文件名判断)。
  2. 只把新增的图片复制到 appdata/Image/(新文件名、新随机后缀,旧文件不受影响)。
  3. 按文件名自然排序确定插入位置:
    • 找到「排序后下一张已引用的图片」,把新块插到那张图的文本上方;
    • 如果后面连续几张都还没被引用,就继续往下找;
    • 一直找到底都没有,就作为该小节的最后一张追加。
  4. 新出现的子目录会在文末追加新的 ## 子目录 小节;md 原本是平铺结构(没有 ##)时不造标题, 直接按全局文件名顺序插入。

举例:md 里已有 01 / 02 / 04,新增 03,结果就是插入到 04 的文本上方。

其他行为:

  • 没有新增图片时,md 一字不改,也不会复制任何文件(日志会说明"没有新增")。
  • 你手写的备注、手工调整过的段落顺序都会原样保留。
  • 保留原文件的换行符(CRLF / LF)与 BOM,避免整篇 diff。
  • 注意:判断依据是"源目录有、md 里没引用"。所以如果你手工删掉了某张图的引用块, 而源目录里那张图还在,下次运行会把它当作未引用的新图再补回去。

⑪ TXT转图片

把 TXT 文件批量渲染为 PNG(中文自动换行)。

  • 参数:TXT 目录、输出目录、字体文件(ttf/ttc)、字号、每行字数、并发线程数。
  • 需要 pillow。

⑫ TXT合并

把指定后缀的文件合并成一个大文件。

  • 参数:目标文件夹、目标后缀(下拉 .txt / .srt / .md / .log,也可直接输入)、是否递归子目录(默认只合并当前层)。
  • 每个文件前会带上原文件名与完整路径,并用 = 分隔线隔开,方便溯源。
  • 输出 全部合并结果<后缀>(默认 全部合并结果.txt);若已存在则自动加 _1、_2,不覆盖。
  • 读取文件时会自动猜编码:优先 chardet 检测结果,然后依次尝试 UTF-8 / GBK / GB2312 / Big5 等。

⑬ TXT重命名

用 TXT 第一行的文字作为新文件名。

  • 自动清理 Windows 非法字符(\ / : * ? " < > |),首行为空的文件跳过。
  • 重名自动去重(加序号),不会覆盖已有文件。

⑭ WebP转JPG

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。

⑰ ReSoBackup备份

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 路径(点「浏览…」后写入)。

打包成 exe

双击 打包.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 路径,删掉即回到"自动查找"。


更新记录

2026-10-20

  • 新增 ⑦ 视频常用压制:调用 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(),日志通过队列回到主线程,执行期间按钮置灰,异常会写进日志并弹窗。

新增一个工具页

  1. 在 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())。
  2. 在 main.py 的 builders 列表里加一项 ("⑱ 新工具", build_xxx_tab)。
  3. 若需要拖放,把 build_xxx_tab 加进上面那个 if builder in (...) 元组,并在页面里调用 app.register_drop_handler(parent, 你的回调)。
  4. python 文件工具箱.py 自测,再 打包.bat。

约定

  • 注释与界面文案用中文;文件名、变量名用英文。
  • 任何写文件的地方都要考虑"目标已存在":跳过或改名,不要直接覆盖。
  • 所有用户可见的进度、跳过原因、失败原因都写进日志,不要只弹一个"完成"。

致谢

  • mozjpeg:⑯ 图片压缩的 JPEG 编码器与无损优化工具。
  • ReSoBackup:⑰ 的 Reed-Solomon 分片格式参考实现(原项目为 Go 版,此处为 Python 重写)。
  • FFmpeg:⑦ 视频压制的编码 / 探测引擎(以外部程序方式调用)。
  • ShanaEncoder:⑦ 的压制参数与字幕样式参考。
  • Pillow:图片读写与缩放。
  • PyCryptodome:AES-256-GCM 加密。

许可

本仓库暂未指定开源许可证;如需在其它项目中复用,请先联系作者。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages