Sign inSign up

caomeiyouren/sharp-cloud-uploader

By caomeiyouren

Updated 5 days ago

一个使用 sharp 进行图片压缩,并上传文件到 R2、S3 或 Vercel Blob 的云函数

Image
0

8.1K

caomeiyouren/sharp-cloud-uploader repository overview

sharp-cloud-uploader

Version Docker Pulls Codecov GitHub Workflow Status Documentation Maintenance License: MIT

一个使用 sharp 进行图片压缩,并上传文件到 R2、S3 或 Vercel Blob 的云函数。支持 Vercel Functions/Cloudflare Workers/Docker 等方式部署。

🏠 主页

https://github.com/CaoMeiYouRen/sharp-cloud-uploader#readme

📦 依赖要求

  • node >=18

🚀 部署

Vercel 部署(推荐)

如果遇到了接口长时间无响应/超时的问题,请在 Vercel 控制台中将环境变量NODEJS_HELPERS设置为 0 后,重新部署,再进行测试。

点击以下按钮一键部署到 Vercel。

Deploy with Vercel

如果使用 Vercel Blob 作为存储,请参考 Vercel Blob 有关文档。

Cloudflare Workers 部署

点击下方按钮一键部署到 Cloudflare Workers。

Deploy to Cloudflare Workers

注意:由于 Cloudflare Workers 不支持 sharp,所以在 Cloudflare Workers 部署时,图片不会经过 sharp 压缩,仅转存原图。

如果想存储到 R2,请将 STORAGE 设置为 r2,并修改 wrangler.toml 中的 r2_buckets 相关配置。

Docker 镜像

支持两种注册表:

支持以下架构:

  • linux/amd64
  • linux/arm64

有以下几种 tags:

Tag描述举例
latest最新latest
{YYYY-MM-DD}特定日期2024-06-07
{sha-hash}特定提交sha-0891338
{version}特定版本1.2.3
Docker Compose 部署

下载 docker-compose.yml

wget https://raw.githubusercontent.com/CaoMeiYouRen/sharp-cloud-uploader/refs/heads/master/docker-compose.yml

检查有无需要修改的配置

vim docker-compose.yml  # 也可以是你喜欢的编辑器

在公网部署时建议设置 AUTH_TOKEN 环境变量,以避免被他人滥用。

请修改 docker-compose.yml 文件中的 environment 字段修改环境变量。

启动

docker-compose up -d

在浏览器中打开 http://{Server IP}:3000 即可查看结果

Node.js 部署

确保本地已安装 Node.js 和 pnpm。

# 下载源码
git clone https://github.com/CaoMeiYouRen/sharp-cloud-uploader.git  --depth=1
cd sharp-cloud-uploader
# 安装依赖
pnpm i --frozen-lockfile
# 构建项目
pnpm build
# 启动项目
pnpm start

在浏览器中打开 http://{Server IP}:3000 即可查看结果

请修改 .env 文件修改环境变量。

👨‍💻 使用

如果在本地部署,基础路径为 http://localhost:3000

在服务器或云函数部署则为 http(s)://{Server IP}

例如:

如果基础路径为 https://example.vercel.app,则 //upload-from-url 的完整路径为 https://example.vercel.app/upload-from-url

1. 上传图片接口
1.1 从 URL 上传图片

接口路径: /upload-from-url

请求方法: POST

请求参数:

  • url: 图片的 URL 地址 (必填)

请求示例:

{
    "url": "https://example.com/image.jpg"
}

响应示例:

{
    "url": "https://example.com/bucket-prefix/20231001123456789-abcdefg.jpg",
    "success": true,
    "status": 200
}

错误响应示例:

{
    "status": 400,
    "message": "URL is required"
}
1.2 从请求体上传图片

接口路径: /upload-from-body

请求方法: POST

请求参数:

  • 图片数据: 二进制数据 (必填)

请求示例:

curl -X POST -H "Content-Type: image/jpeg" --data-binary @image.jpg http://localhost:3000/upload-from-body

响应示例:

{
    "url": "https://example.com/bucket-prefix/20231001123456789-abcdefg.jpg",
    "success": true,
    "status": 200
}

错误响应示例:

{
    "status": 400,
    "message": "Invalid image format"
}
2. 代码示例
2.1 使用 fetch 从 URL 上传图片
const uploadFromUrl = async () => {
    const url = "https://example.com/image.jpg";
    const response = await fetch("http://localhost:3000/upload-from-url", {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({ url }),
    });
    const data = await response.json();
    console.log(data);
};

uploadFromUrl();
2.2 使用 fetch 从请求体上传图片
const uploadFromBody = async () => {
    const imageFile = document.getElementById("image-file").files[0];
    const reader = new FileReader();
    reader.onload = async () => {
        const response = await fetch("http://localhost:3000/upload-from-body", {
            method: "POST",
            headers: {
                "Content-Type": imageFile.type,
            },
            body: reader.result,
        });
        const data = await response.json();
        console.log(data);
    };
    reader.readAsArrayBuffer(imageFile);
};

uploadFromBody();
3. MCP Server(AI Agent 调用)

本项目支持 Model Context Protocol (MCP),可将图片上传能力暴露为标准化工具,供 Claude Desktop、Cursor、VS Code Copilot 等 AI 应用直接调用。

3.1 本地模式(stdio)

适用于本地 AI 工具集成,通过标准输入输出进行通信。

构建本地入口:

pnpm run build    # 会同时生成 dist/mcp-local.mjs

在 Claude Desktop 中配置:

编辑 Claude Desktop 的 claude_desktop_config.json

{
    "mcpServers": {
        "sharp-cloud-uploader": {
            "command": "node",
            "args": ["/path/to/sharp-cloud-uploader/dist/mcp-local.mjs"],
            "env": {
                "STORAGE_TYPE": "s3",
                "S3_REGION": "auto",
                "S3_BUCKET_NAME": "images",
                "S3_ACCESS_KEY_ID": "<your-key>",
                "S3_SECRET_ACCESS_KEY": "<your-secret>",
                "S3_ENDPOINT": "https://xxx.r2.cloudflarestorage.com",
                "S3_BASE_URL": "https://oss.example.com",
                "BUCKET_PREFIX": "uploads/"
            }
        }
    }
}

快速启动(开发调试):

pnpm run mcp:local:dev    # 开发模式,使用 tsx 直接运行源码
pnpm run mcp:local        # 生产模式,使用编译产物
3.2 远程模式(HTTP)

远程模式已集成到服务中,随 Vercel / Docker 部署自动启用,挂载在 /mcp 端点。

无需额外配置,AI 应用可通过 MCP Streamable HTTP 协议直接访问:

POST https://your-app.vercel.app/mcp

若设置了 AUTH_TOKEN 环境变量,MCP 客户端需携带 Authorization: Bearer <token> 请求头。

3.3 可用工具
工具名描述
upload_image_from_url从远程 URL 下载图片,使用 sharp 压缩后上传到云存储
upload_image_from_base64接收 Base64 编码的图片数据,压缩后上传到云存储
get_runtime_info查询服务运行状态和配置(非敏感信息)

示例对话(适用于 Claude Desktop):

用户:帮我把 https://example.com/photo.jpg 这张图片上传到我的图床

Claude:调用 upload_image_from_url 工具,传入 { "url": "https://example.com/photo.jpg", "quality": 90 },返回压缩后的图片链接 https://oss.example.com/uploads/20260101120000000-abc1234.jpg

环境变量配置

请参考 .env 文件中的注释。

# 运行端口
PORT=3000

# 超时时间(ms)
# 如果在 vercel 中运行,则还要修改 vercel.json 中的 maxDuration 字段(单位:秒)
TIMEOUT=60000

NODEJS_HELPERS=0
# 是否写入日志到文件
LOGFILES=false

# 日志级别
# LOG_LEVEL=http

# 最大请求体大小(字节),默认 100MB
# 受 Vercel Functions 的限制,通过请求体上传时最大不超过 4.5 MB(通过 url 上传则不受限制),详见 https://vercel.com/docs/storage/vercel-blob/server-upload
# 受 Cloudflare Workers 的限制,通过请求体上传时最大不超过 100 MB(通过 url 上传则不受限制),详见 https://developers.cloudflare.com/workers/platform/limits
# MAX_BODY_SIZE=104857600

# 图片压缩质量(1-100),默认 90
# IMAGE_QUALITY=90

# 授权密钥(Bearer 认证)。可选,如果设置,则所有请求都需要携带此密钥
AUTH_TOKEN=

# 文件名前缀
# BUCKET_PREFIX=

# 存储类型,可选值:s3, r2, vercel-blob
# 如果服务部署在 Cloudflare Workers,并且想要存储到 R2,则可以设置为 'r2',此时需要修改 wrangler.toml 中的 r2_buckets 相关配置;
# 如果服务部署在其他平台,想要存储到 R2,请使用 R2 的 S3 兼容接口,参考 https://developers.cloudflare.com/r2/api/s3/api,此时设置为 's3'
# STORAGE_TYPE=s3

# S3 基础 URL
# S3_BASE_URL=

# S3 区域
# S3_REGION=

# S3 存储桶名称
# S3_BUCKET_NAME=

# S3 访问密钥 ID
# S3_ACCESS_KEY_ID=

# S3 秘密访问密钥
# S3_SECRET_ACCESS_KEY=

# S3 端点
# S3_ENDPOINT=

# Vercel Blob 令牌,参考 https://vercel.com/docs/storage/vercel-blob
# VERCEL_BLOB_TOKEN=

# R2 基础 URL,仅 Cloudflare Workers 绑定 Cloudflare R2 Storage 可用
# R2_BASE_URL=

🛠️ 开发

npm run dev

🔧 编译

npm run build

🧪 测试

npm run test           # 运行所有测试
npm run test:watch     # watch 模式
npm run test:coverage  # 覆盖率报告

🔍 Lint

npm run lint

💾 Commit

npm run commit

👤 作者

CaoMeiYouRen

🤝 贡献

欢迎 贡献、提问或提出新功能!
如有问题请查看 issues page.
贡献或提出新功能可以查看contributing guide.

💰 支持

如果觉得这个项目有用的话请给一颗 ⭐️,非常感谢

在爱发电支持我 become a patreon

🌟 Star History

Star History Chart

📝 License

Copyright © 2024 CaoMeiYouRen.
This project is MIT licensed.


This README was generated with ❤️ by cmyr-template-cli

Tag summary

Content type

Image

Digest

sha256:a94b17c80

Size

40.2 MB

Last updated

5 days ago

docker pull caomeiyouren/sharp-cloud-uploader