Back to skills
extension
Category: Development & EngineeringNo API key required

图片缩放

图片尺寸缩放(resize)技能。能缩放、改尺寸、调整大小、改分辨率,改格式。

personAuthor: neuhanlihubModelScope

image-resize — 图片尺寸缩放

用确定性脚本(Pillow + LANCZOS 重采样)缩放图片。核心原则:不猜尺寸、不覆盖原文件、输出必须校验

工作流程

  1. 解析用户意图 → 确定目标尺寸与缩放模式(见下方映射表)
  2. 有歧义时先向用户确认,再执行
  3. 调用 scripts/resize.py(环境准备见下)
  4. 核对脚本最后打印的 JSON 结果(尺寸是否正确、文件大小是否达标),不达标就调整参数重跑
  5. 用 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):

  1. 若当前已在虚拟环境中($VIRTUAL_ENV 已设置): macOS / Linux 用 "$VIRTUAL_ENV/bin/python",Windows 用 "%VIRTUAL_ENV%\Scripts\python"
  2. 系统 Python 已装 Pillow:python3 -c "import PIL" 成功即用 python3 (Windows 上命令通常是 pythonpy -3
  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

脚本用法

$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 支持单位:10MB500KB512K10M,纯数字按 KB 算(如 200 = 200KB)
  • 不指定 --outdir 时,输出到原图所在目录
  • 脚本对每个文件打印一行人类可读摘要,最后打印 JSON 数组;核对每项的 after(实际输出尺寸)与 output_bytessize_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 展示输出的图片
  • 文字汇报:原尺寸 → 新尺寸、原大小 → 新大小、所用模式;发生了裁剪、留白或白底合成时必须说明