我写了个 Claude Code Skill,再也不用手动切图传 COS 了

切图、压缩、传 COS、复制链接、粘回代码。一个页面 5 张图就要重复 5 遍。我受够了,写了个 Skill 把这活儿交给 AI。

起因:每天在 Figma 和 COS 控制台之间反复横跳

我做小程序开发,日常跟设计师对接。每次拿到 Figma 设计稿,写代码之前得先处理图片:

  1. Figma 里一张张切图导出
  2. 打开 TinyPNG 网站,把 PNG 拖进去压缩
  3. 登录腾讯云 COS 控制台,上传
  4. 复制 CDN 链接,粘到代码里
  5. 下一张,重复

一个页面 5 张图,这套操作就要走 5 遍。说实话,这活儿谁干谁烦。

后来我发现 Claude Code 有个 Skill 机制,可以教它执行自定义流程。花了2小时折腾出来一个 image-auto-upload Skill,现在图片这块基本不用我操心了。

效果直接看下面的图片

截图里能看到整个链路:

  1. 左上角是 Figma 设计稿
  2. 左侧终端里 Claude Code 在自动识别图片素材
  3. 中间是tinypng压缩 + 上传 COS 的过程
  4. 右上角 COS 控制台里文件已经上传成成功
  5. 右下角是小程序里的最终效果

我就输入了一句"根据 Figma 设计稿实现这个页面(自行切图上传替换)",它自己全办了。

Skill 是个什么东西

简单说,Skill 就是一个文件夹,放在 .claude/skills/ 下面,里面告诉 Claude 怎么完成某个特定任务。

Claude Code 本身能读代码、写代码、跑命令,但它不知道你们项目的图片要传到哪个 COS Bucket,不知道 PNG 要先压缩,不知道上传路径的前缀规则。这些"项目私货",你得自己教它。Skill 就是干这个的。

目录结构长这样:

bash 复制代码
.claude/skills/image-auto-upload/
├── SKILL.md              # 给 Claude 看的操作手册
├── README.md             # 给人看的使用文档
├── resources/            # 放待上传的图片
│   └── README.md
└── scripts/              # 执行脚本
    ├── upload_images.cjs  # Node.js 上传脚本
    └── compress_png.py    # Python 压缩脚本

最核心的是 SKILL.md。Claude 读这个文件来理解:什么时候该用这个技能、具体怎么操作、调什么脚本、结果怎么展示。

SKILL.md 怎么写

这个文件写得好不好,直接决定 Claude 能不能正确干活。我拆开讲讲。

触发场景

markdown 复制代码
## 触发场景

### 场景 1:Figma 设计稿实现
当根据 Figma 设计稿实现页面时,如果设计稿中包含图片素材:
1. 列出可上传的图片素材(图片名称、类型、用途)
2. 等待用户确认需要上传哪些图片
3. 执行上传并返回 CDN URL

### 场景 2:直接上传
当用户直接告知需要上传的图片或图片文件夹时,直接执行上传流程。

两种触发方式。一种是实现 Figma 设计稿时 Claude 自己发现有图片,会先问你要不要上传;另一种是你直接说"上传图片",它立刻执行。

我一开始只写了第二种,后来发现配合 Figma Agent 用的时候,Claude 不知道该主动处理图片,还得我手动提醒。加上第一种之后就顺畅了。

处理流程

objectivec 复制代码
将图片放入 resources/ 文件夹
      │
      ▼
  是图片文件?(png/jpg/jpeg/webp/gif/svg)
      │
  ┌───┴───┐
 YES     NO → 跳过
  │
  ▼
  是 PNG 格式?
  ┌───┴───┐
 YES     NO
  │       │
  ▼       │
自动压缩   │
  │       │
  └───┬───┘
      │
      ▼
 上传到 Tencent COS
      │
      ▼
  返回 CDN URL
      │
      ▼
 自动清理源文件

几个设计上的考虑:

  • PNG 先过 TinyPNG API 压缩再传,JPG/WebP 直接传。PNG 压缩率一般在 60%-80%,省的流量还是挺可观的
  • .DS_Store 之类的杂文件自动跳过,不用手动清理
  • 传完自动删源文件。一开始我没加这个,resources 目录越来越大,后来加了自动清理

输出格式

markdown 复制代码
| 图片名称 | CDN URL |
|----------|---------|
| icon.png | https://xxx.cos.ap-nanjing.myqcloud.com/applet/icon.png |
| bg.jpg   | https://xxx.cos.ap-nanjing.myqcloud.com/applet/bg.jpg |

上传完用表格展示结果,方便直接复制 URL。

两个脚本,一个压缩一个传

整个 Skill 靠两个脚本干活。

PNG 压缩(compress_png.py)

python 复制代码
import tinify

def compress_image(input_path, output_path=None):
    tinify.key = TINYPNG_API_KEY  # 从 .env.skills 读取

    input_size = input_file.stat().st_size
    source = tinify.from_file(str(input_file))
    source.to_file(str(output_path))  # 压缩后覆盖原文件
    output_size = output_path.stat().st_size

    compression_ratio = round((1 - output_size / input_size) * 100, 2)
    return { "compression_ratio": compression_ratio }

逻辑很直白:读文件、调 TinyPNG API、写回去覆盖原文件。TinyPNG 免费额度每月 500 次,个人项目完全够用。

COS 上传(upload_images.cjs)

javascript 复制代码
const COS = require('cos-nodejs-sdk-v5');

// 上传单个文件(分片上传)
function uploadFile(filePath, key) {
  // 1. 初始化分片上传
  cos.multipartInit({ Bucket, Region, Key }, (err, data) => {
    // 2. 上传分片
    cos.multipartUpload({ ... Body: fs.createReadStream(filePath) }, () => {
      // 3. 完成上传
      cos.multipartComplete({ ... });
    });
  });
}

// 上传整个文件夹(递归子目录)
async function uploadFolder(folderPath, prefix) {
  for (const file of files) {
    if (!isImageFile(file)) continue;  // 跳过非图片
    compressPng(file);                  // PNG 先压缩
    await uploadFile(file, key);        // 传到 COS
    fs.unlinkSync(file);               // 删源文件
  }
}

用了 COS SDK 的分片上传,支持递归子目录。上传成功删源文件,失败的留着方便重试。

密钥放哪

COS 密钥和 TinyPNG API Key 放在项目根目录的 .env.skills 里:

bash 复制代码
# .env.skills(记得加 .gitignore)
COS_BUCKET=your-bucket-name
COS_REGION=ap-nanjing
COS_UPLOAD_PREFIX=applet
TINYPNG_API_KEY=your-tinypng-api-key

这个文件不进 Git,密钥不会泄露。

实际用起来是什么感觉

配合 Figma 用(我最常用的方式)

我项目里还有个 figma-designer Agent,配置里写了一条:

markdown 复制代码
遇到图片,先自动切到本地,然后调用 skills 进行压缩上传 COS,然后替换代码

所以流程是这样的:

  1. 我在 Figma 里选中要实现的页面
  2. 在 Claude Code 里说"根据 Figma 设计稿实现这个页面"
  3. Claude 通过 Figma MCP 读设计稿,识别出图片素材
  4. 自动导出图片 → 压缩 PNG → 传 COS → 拿到 CDN URL
  5. 用 URL 替换代码里的图片引用,生成 Vue 组件

我只管最后看一眼代码对不对。中间图片那一堆事,完全不用管。

说实话第一次跑通的时候还挺意外的,没想到几个工具串起来能这么顺。

手动传几张图

有时候设计师单独丢几张图过来,不走 Figma 流程:

scss 复制代码
我:帮我上传 resources 里的图片

Claude:发现 resources 目录下有 3 张图片:
- banner.png (PNG,将自动压缩)
- icon-success.png (PNG,将自动压缩)
- photo.jpg (JPG,直接上传)

正在处理...

[banner.png] 正在压缩 PNG... 压缩完成 (72% reduction)
[banner.png] 上传完成
[icon-success.png] 正在压缩 PNG... 压缩完成 (65% reduction)
[icon-success.png] 上传完成
[photo.jpg] 上传完成

========== 上传完成 ==========
成功: 3 个文件
失败: 0 个文件

| 图片名称 | CDN URL |
|----------|---------|
| banner.png | https://xxx.cos.../applet/banner.png |
| icon-success.png | https://xxx.cos.../applet/icon-success.png |
| photo.jpg | https://xxx.cos.../applet/photo.jpg |

源文件已自动清理。

批量传一整套图

比如一次性传一套图标:

arduino 复制代码
resources/
├── icons/
│   ├── home.png
│   ├── cart.png
│   └── user.png
└── backgrounds/
    ├── login-bg.jpg
    └── main-bg.jpg

上传后目录结构原样保留:

bash 复制代码
applet/icons/home.png
applet/icons/cart.png
applet/icons/user.png
applet/backgrounds/login-bg.jpg
applet/backgrounds/main-bg.jpg

这个我踩过坑。一开始上传脚本不支持子目录,所有文件都平铺到根路径下,文件名一冲突就覆盖了。后来加了递归目录支持才解决。

想自己搞一个?照着来

1. 建目录

bash 复制代码
mkdir -p .claude/skills/image-auto-upload/{scripts,resources}

2. 装依赖

bash 复制代码
# PNG 压缩
pip install tinify

# COS 上传
npm install cos-nodejs-sdk-v5

3. 配环境变量

项目根目录建 .env.skills

bash 复制代码
COS_BUCKET=your-bucket-name
COS_REGION=ap-nanjing
COS_UPLOAD_PREFIX=your-prefix
TINYPNG_API_KEY=your-tinypng-api-key

TinyPNG API Key 去 tinypng.com/developers 申请,免费的,每月 500 次额度。

4. 写 SKILL.md

这步最花时间,也最值得花时间。几个经验:

  1. 触发场景写清楚,不然 Claude 不知道什么时候该用
  2. 流程用流程图或步骤列表,别写大段文字
  3. 命令给完整的,能直接复制执行的那种
  4. 定义好输出格式,不然每次返回的结果格式都不一样

我第一版 SKILL.md 写得太简略,Claude 经常漏步骤。后来补了流程图和具体命令,就稳定多了。

5. 加 .gitignore

bash 复制代码
echo ".env.skills" >> .gitignore
echo ".claude/skills/image-auto-upload/resources/*" >> .gitignore
echo "!.claude/skills/image-auto-upload/resources/README.md" >> .gitignore

到底省了多少事

列个对比吧:

操作 手动 用 Skill
切图导出 一张张从 Figma 导出 自动识别导出
PNG 压缩 开 TinyPNG 网站拖拽 自动调 API
上传 COS 登控制台手动传 脚本自动传
复制链接 一个个复制 URL 表格直接给
替换代码 手动粘贴 自动替换
5 张图耗时 大概 10 分钟 30 秒左右

代码量也不大,Python 脚本 136 行,Node.js 脚本 290 行。写 SKILL.md 反而花的时间更多,因为要反复调试 Claude 的理解是否准确。

说到底,Skill 就是把你脑子里"这个项目图片该怎么处理"的经验,写成 Claude 能看懂的文档。教一次,后面就不用再操心了。

如果你项目里也有类似的重复操作,可以试试写个 Skill。不一定是图片上传,任何有固定流程的事情都行。

相关推荐
程序员小假6 分钟前
我们来说说 Agent 的基础框架是什么?
agent
excel40 分钟前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
ZC跨境爬虫1 小时前
模块化烹饪小程序开发日记 Day7:(菜谱详情接口开发与JSON数据读取全流程)
前端·javascript·css·ui·微信小程序·json
এ慕ོ冬℘゜1 小时前
JS 前端基础面试题
开发语言·前端·javascript
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2026-05-25
前端·人工智能·经验分享·chatgpt·html
冬奇Lab1 小时前
一天一个开源项目(第112篇):Knowledge Work Plugins - Anthropic 官方发布的职能专家插件库
人工智能·开源·claude
冬奇Lab1 小时前
Agent系列(五):意图识别与路由——让 Agent 听懂用户在说什么
人工智能·llm·agent
IT_陈寒2 小时前
Java的Optional差点让我掉坑里,这几个坑你别踩
前端·人工智能·后端
粉嘟小飞妹儿2 小时前
JavaScript对象创建的几种灵活方法
前端
前端小万3 小时前
2026年了,为什么我突然开始做GZH?
前端