image-resize — 图片尺寸缩放
用确定性脚本(Pillow + LANCZOS 重采样)缩放图片。核心原则:不猜尺寸、不覆盖原文件、输出必须校验。
工作流程
- 解析用户意图 → 确定目标尺寸与缩放模式(见下方映射表)
- 有歧义时先向用户确认,再执行
- 调用
scripts/resize.py(环境准备见下) - 核对脚本最后打印的 JSON 结果(尺寸是否正确、文件大小是否达标),不达标就调整参数重跑
- 用 present_files 展示新图,并向用户汇报:原尺寸 → 新尺寸、原大小 → 新大小、使用的模式
意图 → 参数映射
| 用户说法 | 参数 |
|---|---|
| 宽度调成 800 / 高度 600 | --width 800 或 --height 600(等比) |
| 改成 1920×1080(接受拉伸变形) | --width 1920 --height 1080 --mode exact |
| 改成 1920×1080,不变形,裁掉多余 | --width 1920 --height 1080 --mode cover(填满 + 居中裁剪) |
| 改成 1920×1080,不变形,完整保留 | --width 1920 --height 1080 --mode contain(等比放进目标框,其余留白) |
| 缩小到 50% / 放大 2 倍 | --percent 50 / --scale 2 |
| 顺便转成 webp / png / jpeg | --format webp(默认 keep,保留原格式) |
| 文件控制在 10MB 以内 / 500KB 以内 | --max-size 10MB / --max-size 500KB(支持 KB/MB 单位,纯数字按 KB 算;仅 jpeg/webp 有效) |
| 多张图片统一处理 | 把多个文件路径一起传给脚本(一次调用,不要循环调用) |
四种模式语义:
- fit:保持宽高比。只给一个维度或
--scale/--percent时,等比精确缩放到该尺寸(可以放大);同时给了宽+高且比例与原图不同时,只缩不放地塞进目标框(不裁剪、不留白,实际尺寸可能比目标小) - exact:精确拉伸到目标尺寸(会变形)
- cover:等比缩放填满目标框,居中裁掉超出部分(适合做封面图)
- contain:等比缩放进目标框,不足处留白(默认白底)
文件名里的尺寸取自实际输出尺寸,不是请求的目标尺寸——fit 模式下二者可能不同,以文件名和 JSON 里的
after为准。
必须遵守
- 歧义先问:「改成 800」且图片不是正方形(是宽还是高?)、「不变形」但给了两个尺寸(是裁掉还是留白?)——这几种情况结果差异很大,先确认再动手,避免返工。
- 永不覆盖原文件:脚本自动输出为
原名_WxH.ext新文件,输出路径永远不会等于输入路径。绝不要把输出重定向回原文件,也不要事后手动覆盖。 - 透明度保护:带 alpha 通道的 PNG/webp 不要主动转成 JPEG(透明会丢失)。用户明确要求时脚本会自动用白底合成,但要在回复里告知用户「透明背景已变为白底」。
- 放大提醒:像素放大不会提升清晰度。放大后脚本会在 JSON 的
notes里标注upscaled: interpolation adds no new detail;目标尺寸超过原图 2 倍时,在回复中提醒一句,让用户知情。 - 放大请优先用原图:链式处理(先缩小再放大)会永久丢失细节。若原图还在,一律用原图重新缩放到目标尺寸,而不是拿已缩小的中间产物去放大。
- EXIF 方向:脚本自动按 EXIF 信息摆正方向,无需额外处理。
- 动图:GIF 等动图只处理第一帧,要在回复中说明。
- 跨平台一致性:处理必须走本技能的
scripts/resize.py(纯 Python + Pillow)。禁止改用 sips、ImageMagick 等操作系统专属工具——它们只有部分平台可用,且重采样算法与 Pillow 不同,会导致不同系统上结果不一致。macOS、Linux、Windows 上脚本行为完全相同。
环境准备(跨平台:macOS / Linux / Windows)
脚本只依赖 Pillow,按以下顺序确定可用的 Python 解释器(记为 $PY):
- 若当前已在虚拟环境中(
$VIRTUAL_ENV已设置): macOS / Linux 用"$VIRTUAL_ENV/bin/python",Windows 用"%VIRTUAL_ENV%\Scripts\python" - 系统 Python 已装 Pillow:
python3 -c "import PIL"成功即用python3(Windows 上命令通常是python或py -3) - 都不行则在技能目录创建隔离 venv(只做一次):
- macOS / Linux:
python3 -m venv <技能目录>/.venv && <技能目录>/.venv/bin/python -m pip install Pillow - Windows:
python -m venv <技能目录>\.venv && <技能目录>\.venv\Scripts\python -m pip install Pillow
- macOS / Linux:
脚本用法
$PY <本技能目录>/scripts/resize.py INPUT [INPUT2 ...] \
(--width W | --height H | --percent P | --scale S) \
[--mode fit|exact|cover|contain] \
[--format keep|jpeg|png|webp] [--quality 85] \
[--max-size 10MB] [--outdir DIR] [--pad-color '#FFFFFF']
--mode缺省规则:同时给宽+高 → exact;只给一个维度或用 percent/scale → fit--max-size支持单位:10MB、500KB、512K、10M,纯数字按 KB 算(如200= 200KB)- 不指定
--outdir时,输出到原图所在目录 - 脚本对每个文件打印一行人类可读摘要,最后打印 JSON 数组;核对每项的
after(实际输出尺寸)与output_bytes,size_ok为 false 说明没压到目标大小
示例(宽度 800 等比缩放):
$PY .../scripts/resize.py photo.jpg --width 800
# photo.jpg: 4000x3000 -> photo_800x600.jpg 800x600 (2.9MB -> 180KB) mode=fit
# [{"input": "photo.jpg", "output": "photo_800x600.jpg", "before": [4000, 3000], "after": [800, 600], ...}]
完成后的动作
- 用 present_files 展示输出的图片
- 文字汇报:原尺寸 → 新尺寸、原大小 → 新大小、所用模式;发生了裁剪、留白或白底合成时必须说明
Scan to join WeChat group