完善打包与代理支持文档
parent
adca311c0a
commit
7d58acf0b4
|
|
@ -1,6 +1,11 @@
|
|||
__pycache__
|
||||
.venv
|
||||
tinify_keys.json
|
||||
tinify_usage.json
|
||||
optimized
|
||||
source
|
||||
uv.lock
|
||||
build/
|
||||
dist/
|
||||
*.spec
|
||||
*.exe
|
||||
|
|
|
|||
184
README.md
184
README.md
|
|
@ -1,17 +1,19 @@
|
|||
# TinyPNG 批量压缩工具
|
||||
|
||||
这是一个基于 Tinify/TinyPNG Python SDK 的批量图片压缩和格式转换工具。支持 GUI 界面、多个 API Key 按顺序接力使用、官方额度同步、批量转换格式,以及递归处理目录。
|
||||
这是一个基于 Tinify/TinyPNG Python SDK 的批量图片压缩和格式转换工具。它提供图形界面和命令行两种使用方式,支持多个 API Key 接力使用、官方额度同步、批量格式转换、递归处理目录、HTTP/SOCKS5 代理,以及 Windows 二进制打包分发。
|
||||
|
||||
## 功能
|
||||
|
||||
- 图形界面选择输入目录和输出目录。
|
||||
- 支持多个 Tinify API Key,每个 Key 默认每月 500 张额度,处理时会先用完前一个 Key,再切换到下一个。
|
||||
- 启动处理前可同步官方本月已用额度。
|
||||
- 支持 PNG、JPG/JPEG、WebP、AVIF 图片。
|
||||
- 支持转换为 png、jpeg、webp、avif,也支持“全部格式”一次输出四种格式。
|
||||
- GUI 图形界面,适合日常批量处理图片。
|
||||
- CLI 命令行入口,适合脚本化或自动化处理。
|
||||
- 支持多个 Tinify API Key,每个 Key 默认每月 500 张额度。
|
||||
- 支持处理前同步官方本月已用额度。
|
||||
- 支持 PNG、JPG/JPEG、WebP、AVIF 输入。
|
||||
- 支持输出源格式、PNG、JPEG、WebP、AVIF,也可以一次输出全部格式。
|
||||
- 支持递归扫描目录。
|
||||
- 支持覆盖已有输出文件或跳过已有文件。
|
||||
- 支持试运行,只预览计划,不调用 Tinify API。
|
||||
- 支持试运行,只预览处理计划,不调用 Tinify API。
|
||||
- 支持 HTTP 代理和 SOCKS5 代理。
|
||||
|
||||
## 目录说明
|
||||
|
||||
|
|
@ -22,12 +24,42 @@ C:\dev\py\tinypng
|
|||
├─ tinypng_gui.py GUI 程序
|
||||
├─ tinypng_balancer.py 命令行和核心处理逻辑
|
||||
├─ run_gui.bat 双击启动 GUI
|
||||
├─ tinify_keys.json 实际 API Key 配置文件
|
||||
├─ tinify_usage.json 本月额度缓存文件,运行后自动生成
|
||||
├─ tinify_keys.sample.json API Key 配置模板
|
||||
├─ tinify_keys.json 实际 API Key 配置文件,本地使用,不提交 Git
|
||||
├─ tinify_usage.json 本月额度缓存文件,本地使用,不提交 Git
|
||||
├─ pyproject.toml uv 项目依赖配置
|
||||
└─ uv.lock uv 锁定文件
|
||||
```
|
||||
|
||||
打包后使用 `--onedir` 文件夹版时,默认目录会改为可执行文件所在目录:
|
||||
|
||||
```text
|
||||
dist\tinypng-gui
|
||||
├─ tinypng-gui.exe
|
||||
├─ _internal\
|
||||
├─ source\
|
||||
├─ optimized\
|
||||
├─ tinify_keys.json
|
||||
└─ tinify_usage.json
|
||||
```
|
||||
|
||||
`source`、`optimized` 和 JSON 配置文件不会放到 `_internal` 里。
|
||||
|
||||
## 安装依赖
|
||||
|
||||
项目使用 `uv` 管理依赖:
|
||||
|
||||
```powershell
|
||||
cd C:\dev\py\tinypng
|
||||
uv sync
|
||||
```
|
||||
|
||||
主要依赖:
|
||||
|
||||
- `tinify`:TinyPNG 官方 Python SDK。
|
||||
- `requests[socks]`:为 HTTP/SOCKS5 代理提供支持。
|
||||
- `pyinstaller`:开发依赖,用于打包 Windows 二进制。
|
||||
|
||||
## 启动 GUI
|
||||
|
||||
推荐直接双击:
|
||||
|
|
@ -43,13 +75,11 @@ cd C:\dev\py\tinypng
|
|||
uv run tinypng_gui.py
|
||||
```
|
||||
|
||||
程序通过 `uv run` 启动,会自动使用 `pyproject.toml` 中声明的 `tinify` SDK 依赖。
|
||||
|
||||
## 配置 API Key
|
||||
|
||||
打开 GUI 后点击 `填写 API Key`。
|
||||
|
||||
支持以下输入方式:
|
||||
支持一行一个:
|
||||
|
||||
```text
|
||||
KEY_1
|
||||
|
|
@ -81,19 +111,43 @@ KEY_3
|
|||
|
||||
不要把真实 API Key 写入 `tinify_keys.sample.json`,它只作为模板示例。
|
||||
|
||||
## 代理格式
|
||||
|
||||
不需要代理时留空。
|
||||
|
||||
HTTP 代理:
|
||||
|
||||
```text
|
||||
http://127.0.0.1:7890
|
||||
```
|
||||
|
||||
SOCKS5 代理:
|
||||
|
||||
```text
|
||||
socks5://127.0.0.1:1080
|
||||
```
|
||||
|
||||
带账号密码:
|
||||
|
||||
```text
|
||||
http://username:password@127.0.0.1:7890
|
||||
socks5://username:password@127.0.0.1:1080
|
||||
```
|
||||
|
||||
常见代理软件的 HTTP 端口可能是 `7890`、`10809`,SOCKS5 端口可能是 `1080`、`10808`。以代理软件里实际显示的端口为准。
|
||||
|
||||
## GUI 使用流程
|
||||
|
||||
1. 把图片放入当前目录下的 `source` 文件夹。
|
||||
2. 双击 `run_gui.bat` 打开界面。
|
||||
3. 点击 `填写 API Key`,粘贴一个或多个 API Key 并保存。
|
||||
4. 确认输入目录为 `source`。
|
||||
5. 选择输出目录,默认是 `optimized`。
|
||||
6. 按需选择转换格式、递归扫描、覆盖输出、同步官方额度等选项。
|
||||
7. 点击 `开始处理`。
|
||||
1. 把图片放入 `source` 文件夹,或在界面中选择其他输入目录。
|
||||
2. 点击 `填写 API Key`,粘贴一个或多个 API Key 并保存。
|
||||
3. 如需代理,在代理输入框填写 HTTP 或 SOCKS5 地址。
|
||||
4. 确认输出目录,默认是 `optimized`。
|
||||
5. 按需选择转换格式、递归扫描、覆盖输出、试运行、同步官方额度等选项。
|
||||
6. 点击 `开始处理`。
|
||||
|
||||
## 转换格式
|
||||
|
||||
`转换格式` 默认是 `保持原格式`。
|
||||
`转换格式` 默认选择 `源格式` 和 `webp`。
|
||||
|
||||
可选值:
|
||||
|
||||
|
|
@ -102,10 +156,9 @@ KEY_3
|
|||
- `jpeg` / `jpg`:输出 JPEG。
|
||||
- `webp`:输出 WebP。
|
||||
- `avif`:输出 AVIF。
|
||||
- 可多选,例如默认会同时选择 `源格式` 和 `webp`,每张图片会输出源格式压缩结果和 WebP 结果。
|
||||
- 命令行的 `all` 会输出源格式、`.png`、`.jpg`、`.webp`、`.avif`。
|
||||
- `all`:命令行专用,一次输出源格式、PNG、JPEG、WebP、AVIF。
|
||||
|
||||
注意:转换、缩放等 Tinify API 操作可能会消耗压缩额度。“全部格式”会为每张输入图片生成多个输出,因此额度消耗也会更多。
|
||||
注意:转换、缩放等 Tinify API 操作可能会消耗压缩额度。一次输出多个格式时,每张输入图片会产生多个输出,额度消耗也会相应增加。
|
||||
|
||||
## 额度同步
|
||||
|
||||
|
|
@ -153,6 +206,12 @@ uv run tinypng_balancer.py source -o optimized --convert source --convert webp
|
|||
uv run tinypng_balancer.py source -o optimized --convert all
|
||||
```
|
||||
|
||||
缩放:
|
||||
|
||||
```powershell
|
||||
uv run tinypng_balancer.py source -o optimized --resize-method fit --width 1200 --height 1200
|
||||
```
|
||||
|
||||
试运行:
|
||||
|
||||
```powershell
|
||||
|
|
@ -165,6 +224,59 @@ uv run tinypng_balancer.py source -o optimized --dry-run
|
|||
uv run tinypng_balancer.py source -o optimized --no-sync-usage
|
||||
```
|
||||
|
||||
指定配置和用量文件:
|
||||
|
||||
```powershell
|
||||
uv run tinypng_balancer.py source -o optimized --config tinify_keys.json --state tinify_usage.json
|
||||
```
|
||||
|
||||
生成配置模板:
|
||||
|
||||
```powershell
|
||||
uv run tinypng_balancer.py --init-config tinify_keys.json
|
||||
```
|
||||
|
||||
## 打包 Windows 二进制
|
||||
|
||||
推荐打包为 `onedir` 文件夹版:
|
||||
|
||||
```powershell
|
||||
uv run pyinstaller --noconfirm --clean --onedir --windowed --name tinypng-gui --add-data "tinify_keys.sample.json;." tinypng_gui.py
|
||||
```
|
||||
|
||||
输出目录:
|
||||
|
||||
```text
|
||||
dist\tinypng-gui\
|
||||
```
|
||||
|
||||
启动文件:
|
||||
|
||||
```text
|
||||
dist\tinypng-gui\tinypng-gui.exe
|
||||
```
|
||||
|
||||
分发时需要把整个 `dist\tinypng-gui\` 文件夹一起发出去,因为 `_internal\` 里包含运行依赖。
|
||||
|
||||
不推荐日常使用 `--onefile` 单文件版。单文件版启动时会先解压依赖到系统临时目录;文件夹版不会把依赖释放到 Temp,路径也更容易管理。
|
||||
|
||||
## Git 忽略
|
||||
|
||||
以下文件通常不需要提交:
|
||||
|
||||
```gitignore
|
||||
tinify_keys.json
|
||||
tinify_usage.json
|
||||
optimized
|
||||
source
|
||||
build/
|
||||
dist/
|
||||
*.spec
|
||||
*.exe
|
||||
```
|
||||
|
||||
是否提交 `pyproject.toml` 中的 `pyinstaller` 开发依赖,取决于是否希望项目自带打包能力。当前项目保留该开发依赖,方便以后重复打包。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 提示 No module named 'tinify'
|
||||
|
|
@ -177,15 +289,29 @@ uv run tinypng_gui.py
|
|||
|
||||
或者双击 `run_gui.bat`。
|
||||
|
||||
### 没有找到图片
|
||||
### 填写 socks5:// 代理后提示缺少 SOCKS 支持
|
||||
|
||||
确认图片放在输入目录中。默认输入目录是:
|
||||
确认已经安装 SOCKS 依赖:
|
||||
|
||||
```text
|
||||
C:\dev\py\tinypng\source
|
||||
```powershell
|
||||
uv sync
|
||||
```
|
||||
|
||||
支持的扩展名包括:
|
||||
如果是旧环境,可以重新添加依赖:
|
||||
|
||||
```powershell
|
||||
uv add requests[socks]
|
||||
```
|
||||
|
||||
然后重新打包二进制。
|
||||
|
||||
### 打包版路径指向 _internal
|
||||
|
||||
请使用新版代码重新打包。GUI 会在打包环境中使用 `tinypng-gui.exe` 所在目录作为默认目录,不会把 `source`、`optimized`、`tinify_keys.json` 放进 `_internal`。
|
||||
|
||||
### 没有找到图片
|
||||
|
||||
确认图片放在输入目录中。支持的扩展名包括:
|
||||
|
||||
```text
|
||||
.png .jpg .jpeg .webp .avif
|
||||
|
|
@ -197,4 +323,4 @@ C:\dev\py\tinypng\source
|
|||
|
||||
### 全部格式输出时额度消耗变多
|
||||
|
||||
这是正常的。因为每张图片会分别转换为 PNG、JPEG、WebP、AVIF 四种格式,每个输出都可能消耗 Tinify 额度。
|
||||
这是正常的。因为每张图片会分别转换为多个格式,每个输出都可能消耗 Tinify 额度。
|
||||
|
|
|
|||
|
|
@ -4,5 +4,11 @@ version = "0.1.0"
|
|||
description = "TinyPNG GUI batch compressor with multiple Tinify API keys."
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"requests[socks]>=2.32.5",
|
||||
"tinify>=1.6.0",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"pyinstaller>=6.20.0",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import os
|
||||
import queue
|
||||
import sys
|
||||
import threading
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog, messagebox, ttk
|
||||
|
|
@ -11,7 +12,13 @@ from tkinter import filedialog, messagebox, ttk
|
|||
from tinypng_balancer import BatchArgs, CONVERT_SOURCE, CONVERT_TYPES, run_batch, write_json
|
||||
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
def app_base_dir():
|
||||
if getattr(sys, "frozen", False):
|
||||
return os.path.dirname(os.path.abspath(sys.executable))
|
||||
return os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
BASE_DIR = app_base_dir()
|
||||
DEFAULT_INPUT_DIR = os.path.join(BASE_DIR, "source")
|
||||
|
||||
|
||||
|
|
@ -50,6 +57,12 @@ class KeyConfigDialog(tk.Toplevel):
|
|||
ttk.Label(top, text="代理").grid(row=2, column=0, sticky="w", pady=4)
|
||||
ttk.Entry(top, textvariable=self.proxy_var).grid(row=2, column=1, columnspan=2, sticky="ew", padx=8, pady=4)
|
||||
|
||||
ttk.Label(
|
||||
top,
|
||||
text="示例: http://127.0.0.1:7890 或 socks5://127.0.0.1:1080,留空则不使用代理",
|
||||
foreground="#666666",
|
||||
).grid(row=3, column=1, columnspan=2, sticky="w", padx=8, pady=(0, 4))
|
||||
|
||||
body = ttk.Frame(self, padding=(12, 0, 12, 12))
|
||||
body.grid(row=1, column=0, sticky="nsew")
|
||||
body.rowconfigure(1, weight=1)
|
||||
|
|
|
|||
Loading…
Reference in New Issue