图序图片工具(tuxu-image-tools)
在用户电脑本机处理图片的命令行工具集。图片全程不出用户电脑:脚本除首次安装依赖(npm 安装 sharp)外不联网、不采集、不上传任何数据。
第一步(必须先做)
每次会话第一次使用本技能时,先运行环境自检,再处理图片:
node scripts/env-check.mjs
- 输出
"ok": true→ 环境就绪,直接继续。 - 输出
"ok": false→ 会尝试自动安装依赖;仍失败时,把 JSON 里error.hint的安装指引原文转告用户,不要自己编步骤。 - 若某个功能脚本报
ENV_MISSING(exit 3),同样先运行上面的自检。
调用约定
- 输入:
--input接单个文件或文件夹(文件夹 = 批量,最多 200 张,不递归子文件夹)。路径含空格或中文必须用引号包裹。也可以把路径作为第一个位置参数。 - 输出:默认写入新目录
<输入位置>/tuxu-output/<子命令>/(按子命令分目录,多步处理的结果互不覆盖),绝不覆盖原图。可用--output指定其他目录。 - 结果:stdout 输出一份 JSON(
summary一行摘要 +files每个文件成败与输入/输出路径)。stderr 是过程日志,可忽略。 - 退出码:
0全部成功;1参数错误;2文件/格式错误(含部分文件失败);3环境依赖缺失。 - 所有脚本都支持
--help查看参数。 - 输出文件名与原图同名(转换格式时换扩展名)。
能力与子命令
1. compress — 压缩图片
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--input |
路径 | 是 | - | 文件或文件夹 |
--target-size |
如 200KB、1.5MB |
与quality二选一 | - | 压到指定体积(不超过为目标) |
--quality |
1-100 整数 | 与target-size二选一 | 80 | 按质量压缩 |
--format |
jpg/png/webp | 否 | 保持原格式 | |
--output |
目录 | 否 | tuxu-output/ |
node scripts/compress.mjs --input "./images/trip" --target-size 200KB
结果示例(所有子命令的 JSON 结构相同):
{
"ok": true,
"partial": false,
"command": "compress",
"summary": "处理完成:成功 3 张,失败 0 张",
"outputDir": "./images/trip/tuxu-output/compress",
"files": [
{ "input": "./images/trip/a.jpg", "output": "./images/trip/tuxu-output/compress/a.jpg",
"ok": true, "format": "jpeg", "width": 1200, "height": 1600,
"sizeBefore": 1818700, "sizeAfter": 203186, "quality": 23 }
]
}
说明:PNG 压到指定体积时使用调色板量化(quality 字段为色板色数);若最低质量仍压不到目标,会输出尽力结果并在 warning 里如实说明。
2. convert — 格式转换
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--format |
jpg/png/webp | 是 | - | 目标格式 |
--quality |
1-100 | 否 | 80 | JPG/WebP 有效 |
--input / --output |
是/否 | 同上 |
node scripts/convert.mjs --input "./screenshots" --format webp
说明:含透明通道的图转 JPG 时自动铺白底。
3. resize — 调整尺寸
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--preset |
预设名或 800x800 |
三选一 | - | 商品主图/详情页/公众号封面/小红书竖图/视频封面/一寸/二寸(详见 references/presets.md) |
--percent |
1-1000 | 三选一 | - | 百分比缩放,如 50 |
--width / --height |
像素 | 三选一 | - | 只给其一则等比缩放 |
--fit |
cover/contain/stretch | 否 | cover | 两维都给时:cover 裁满、contain 完整留白、stretch 拉伸 |
--background |
颜色 | 否 | JPG白/PNG与WebP透明 | contain 的留白底色 |
--no-upscale |
旗标 | 否 | - | 不放大 |
node scripts/resize.mjs --input "./images" --preset 小红书竖图
node scripts/resize.mjs --input photo.jpg --width 800
4. crop — 裁剪
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--ratio |
如 1:1、3:4 |
三选一 | - | 按比例取最大裁剪 |
--width + --height |
像素 | 三选一 | - | 裁指定大小(居中/锚点) |
--region |
x,y,宽,高 |
三选一 | - | 按坐标精确裁剪 |
--anchor |
九宫格位置 | 否 | center | top-left…bottom-right |
node scripts/crop.mjs --input "./images" --ratio 1:1
5. rotate — 旋转与翻转
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--angle |
90/180/270 | 否 | - | 顺时针旋转 |
--flip-horizontal / --flip-vertical |
旗标 | 否 | - | 水平/垂直翻转 |
| 三个都不给 | - | - | 仅按 EXIF 自动摆正(手机照片横竖不对时用) |
node scripts/rotate.mjs --input "./phone-photos"
说明:所有脚本读图时都会自动按 EXIF 摆正方向。
6. watermark — 文字水印(图片 Logo 水印在二期)
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--text |
文字 | 是 | - | 水印内容 |
--position |
九宫格位置 | 否 | bottom-right | |
--tile |
旗标 | 否 | - | -30° 平铺整图 |
--font-size |
像素 | 否 | 短边6% | |
--color |
如 #ffffff |
否 | 白 | 支持 #RRGGBB(AA) |
--opacity |
0.01-1 | 否 | 0.7 | |
--offset-x / --offset-y |
像素 | 否 | 0 |
node scripts/watermark.mjs --input "./sample-images" --text "仅供演示"
7. border — 边框
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--width |
像素 | 至少其一 | 0 | 边框宽度(向外扩展) |
--padding |
像素 | 至少其一 | 0 | 图片与边框间的内边距留白 |
--color |
颜色 | 否 | #000000 | 边框颜色 |
--padding-color |
颜色 | 否 | #ffffff | 内边距颜色 |
node scripts/border.mjs --input photo.jpg --width 16 --padding 24 --padding-color "#f5f5f5"
8. pad — 画布留白
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
--ratio |
如 1:1 |
三选一 | - | 留白到目标宽高比(图片不缩放只补边) |
--preset |
预设名 | 三选一 | - | 留白到预设尺寸 |
--width + --height |
像素 | 三选一 | - | 精确画布尺寸(图片偏大时等比缩小放入) |
--background |
颜色或 transparent | 否 | #ffffff | 留白底色 |
--anchor |
九宫格位置 | 否 | center |
node scripts/pad.mjs --input "./product-images" --preset 商品主图 --background "#ffffff"
不支持(请勿调用本技能,直接告知用户暂不支持)
- 抠图 / 去背景 / 换底色
- 色彩调整(亮度 / 对比度 / 饱和度 / 滤镜 / 灰度)
- HEIC / AVIF / GIF 动图 的输入或转换(含「iPhone 的 HEIC 转 JPG」)
- PDF(图片转 PDF、PDF 转图片)
- 证件照成套出图(人像排版、换底、美颜;只支持把已有照片改成 1 寸/2 寸的尺寸)
- 图片 Logo / 印章水印(目前仅文字水印)
- 任意角度旋转(仅 90/180/270)
用户提出以上需求时,明确说明本技能暂不支持,不要尝试用本技能变通处理。
批量处理
- 把
--input指向文件夹即为批量(不递归,最多 200 张);每张图的成败在结果 JSON 的files数组里。 - 不受支持的文件会被跳过并在 stderr 提示,不会中断整批。
- 部分文件失败时整体退出码为 2,但成功的文件已正常输出,把失败清单转告用户即可。
破坏性操作规则(红线)
- 默认绝不覆盖原图:输出固定写入新的
tuxu-output/<子命令>/目录(按子命令分目录);脚本还会拒绝「输出路径与原图相同」的操作。 - 只有当用户明确要求覆盖原图时才考虑
--output指向原目录,且必须先向用户确认「会覆盖原图,确定吗?」得到肯定答复后再执行。 - 除此之外任何会改动用户文件的操作(删除、移动、改名)都不属于本技能范围。
错误处理
- 脚本失败时,把 JSON 中
error.message(以及error.hint)原文转述给用户;不要猜测或编造原因,不要把堆栈原文丢给用户。 - 退出码含义:
1参数错误(检查命令参数)、2文件/格式问题(见 references/presets.md 的「常见错误与恢复指引」)、3环境问题(回到第一步运行 env-check)。 - 提示用户某个具体文件失败时,引用该文件在
files里的error字段。 - 预设名、调用写法、错误恢复顺序的完整说明在 references/presets.md。