Token导航 LogoToken导航TokenDH.com
Img Convert logo
设计创作stdio官方级别未说明来源级核验

Img Convert

MCP Server

@dutchbase/img-convert

一款快速、支持多种格式转换的图像处理工具,适用于开发者和AI代理。

工具数

4

提示词数

0

GitHub Stars

3

资源数

0
图像处理多平台支持TypeScriptClaude格式转换ClaudeCursor

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

dutchbase

提供方

dutchbase

最后核验

2026/5/17 20:21

运行时

Node.js

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

npx @dutchbase/img-convert

详细介绍

img转换

带Web UI的快速CLI图像转换器。

在以下之间转换图像:

  • JPG格式
  • 便携式网络图形
  • WebP
  • AVIF
  • 图形交换格式
  • 标签式图像文件格式

专为开发人员和人工智能代理而构建。

安装

npx @dutchbase/img-convert

npm install -g @dutchbase/img-convert
# Convert a file
img-convert photo.jpg -f webp --json

# Inspect an image without converting
img-convert info photo.jpg

# Give Claude Code native image conversion tools
img-convert mcp

______________________________________________________________________

______________________________________________________________________

目录

- 转换 - 信息 - 批次 - MCP服务器

- MCP工具 - JSON输出设计 - 清单批处理模式

- convert() - 获取信息() - 批次()

______________________________________________________________________

代理技能

img-convert 船舶a SKILL.md 编码代理可以导入的文件,以获得每个命令、标志、模式和gotcha的完整、结构化的知识,而无需阅读此README。

导入到Claude Code(全局,所有项目)

/instinct-import https://raw.githubusercontent.com/dutchbase/img-converter/main/SKILL.md

作为项目范围的技能导入

/instinct-import https://raw.githubusercontent.com/dutchbase/img-converter/main/SKILL.md --scope project

导入后,任何Claude Code会话都会自动知道:

  • 为给定任务使用哪个接口(CLI与API、MCP与REST)
  • 始终奔跑 img-convert info 转换未知图像之前
  • --json /stderr管道分离合同
  • 每个CLI标志,包括新标志(--grayscale, --rotate, --normalize等等)
  • 的清单格式 batch 子命令
  • 所有MCP工具签名和返回形状
  • Node.js API类型和常用模式
  • 格式陷阱(仅限HEIC输入,alpha→JPEG背景,GIF动画规则)
  • 常见错误以及如何避免

技能文件与包保持同步 SKILL.md.

______________________________________________________________________

为什么转换img

大多数图像转换工具都是为交互式使用而设计的——GUI、web表单、一次性shell命令。 img-convert 专为 程序化使用:CI管道、构建脚本、AI代理工作流和服务器端处理。

关键设计原则:

  • 机器可读输出优先。 --json 每一个命令。 stderr 承载着面向人类的进步。 stdout 携带数据。每个命令都干净地传输到 jq.
  • AI代理优化。 提供本地MCP服务器。Claude Code、Cursor和任何兼容MCP的代理都可以调用 convert_imageget_image_info 作为原生工具——没有shell转义,没有子流程管理,完全类型安全。
  • 可组合。 CLI、Node.js API和REST API都运行相同的 processImage() 引擎盖下的管道。无论调用路径如何,行为都是相同的。
  • 最小的已发布足迹。 npm包的大小约为50KB。完整的Next.js web UI被排除在已发布的包之外——仅 dist/, lib/, types/,以及 cli/ 船。

______________________________________________________________________

安装

全局CLI

npm install -g @dutchbase/img-convert

本地依赖项(Node.js API)

npm install @dutchbase/img-convert

自托管web UI

git clone https://github.com/dutchbase/img-convert
cd img-convert
npm install
npm run dev        # http://localhost:3000
npm run build      # production Next.js build

需求

  • Node.js>=18.0.0
  • Sharp的原生绑定是为Linux x64/arm64、macOS arm64/x64和Windows x64预先构建的。有关其他平台,请参阅 清晰的安装指南.

______________________________________________________________________

CLI参考

转换(默认操作)

img-convert [files...] -f  [options]

files 接受文件路径、glob模式和HTTP/HTTPS URL。当没有提供文件并且stdin是管道时,从stdin读取并写入stdout(管道模式)。

选项

标志默认值描述
-f, --format 必修的。 目标格式: jpeg png webp avif gif tiff
-q, --quality 85编码质量1–100。适用于JPEG、WebP、AVIF、TIFF。PNG从该值导出压缩级别。GIF忽略了它
--width --以像素为单位调整此宽度。默认情况下保持纵横比。
--height --调整到这个高度(像素)。默认情况下保持纵横比。
--no-metadata--删除EXIF/XMP/IPTC元数据。ICC颜色配置文件始终保持不变。
-o, --output input dir将输出文件写入此目录。如果不存在,则自动创建。
-c, --concurrency 4最大并行转换。
--json--将结构化JSON发送到stdout。所有进度和警告都会转到stderr。
--dry-run--展示不写任何东西会写什么。
--quiet--抑制每个文件的进度行。错误摘要仍然显示。
--grayscale--将图像去饱和为灰度。
--rotate --按度旋转。可接受的任何角度;背景色填充空白角落。
--flip--水平翻转(左-右后视镜)。
--flop--垂直翻转(顶部-底部镜子)。
--background --透明区域的背景填充颜色(例如。 #ffffff, rgba(0,0,0,0)).需要清洁PNG→JPEG转换。
--blur ——高斯模糊西格玛(有效范围:0.3-1000)。
--sharpen--使用Sharp的默认参数应用反锐化蒙版锐化。
--normalize--将对比度拉伸到全范围。适用于扫描文档和低对比度图像。
--trim--自动修剪所有边缘的均匀颜色边框像素。

示例

# Single file
img-convert photo.jpg -f webp

# Glob pattern with output directory and quality
img-convert "src/images/*.png" -f avif -q 80 -o dist/images/

# Resize to max 1280px wide, maintain aspect ratio
img-convert banner.png -f jpeg --width 1280 -q 90

# Strip metadata, 4 files at once
img-convert *.jpg -f webp --no-metadata -c 4 -o output/

# Remote URL
img-convert https://example.com/photo.png -f webp -o ./converted/

# Machine-readable output — stdout is pure JSON, stderr is progress
img-convert photo.jpg -f webp --json 2>/dev/null | jq .reduction

# Pipe mode: stdin → stdout (no file args, non-TTY stdin)
cat input.png | img-convert -f webp > output.webp

# Preview without writing
img-convert "*.jpg" -f avif --dry-run --json

# Grayscale + auto contrast for document scans
img-convert scan.jpg -f png --grayscale --normalize

# Flatten PNG transparency to white before JPEG conversion
img-convert logo.png -f jpeg --background "#ffffff"

# Rotate with background fill
img-convert photo.jpg -f jpeg --rotate 90 --background "#000000"

JSON输出形状

单个文件:

{
  "input": "photo.jpg",
  "output": "/absolute/path/to/photo.webp",
  "inputBytes": 204800,
  "outputBytes": 81920,
  "reduction": 60.0,
  "width": 1920,
  "height": 1080,
  "format": "webp",
  "quality": 85
}

多个文件: 每个文件有一个对象的JSON数组。失败的文件包括 "error" 字符串字段,而不是大小/维度数据。

干运行(带 --json):

{
  "input": "photo.jpg",
  "output": "/absolute/path/to/photo.webp",
  "inputBytes": 204800,
  "dryRun": true
}

______________________________________________________________________

info 子命令

检查图像而不进行转换。始终将JSON输出到stdout。支持文件路径和URL。

img-convert info 
img-convert info photo.jpg
img-convert info https://example.com/image.png

输出:

{
  "format": "jpeg",
  "width": 4032,
  "height": 3024,
  "filesize": 3891200,
  "hasAlpha": false,
  "hasExif": true,
  "colorSpace": "srgb",
  "isAnimated": false,
  "channels": 3,
  "density": 72
}

现场参考:

字段类型描述
formatstringSharp检测到的格式: jpeg, png, webp, gif, tiff, avif等等。
widthnumber宽度(像素)
heightnumber高度(像素)
filesizenumber文件大小(字节)
hasAlphaboolean是否存在alpha(透明度)通道
hasExifbooleanEXIF元数据是否存在
colorSpacestring颜色空间: srgb, p3, cmyk, grey等等。
isAnimated布尔值true 用于动画GIF、多页TIFF、动画WebP
channelsnumber通道计数--3=RGB,4=RGBA
densitynumber嵌入在文件元数据中的DPI/PPI。 undefined 如果没有设置。

info 命令是为 转换前检查 --检查 hasAlpha 在转换为JPEG之前,请检查 isAnimated 在剥离框架之前,请在调整大小之前验证尺寸。

______________________________________________________________________

batch 子命令

转换JSON清单文件中定义的图像列表。

img-convert batch  [options]

选项:

标志默认值描述
-c, --concurrency 4并行转换限制
--json--将结果作为JSON数组输出到stdout

清单格式:

[
  {
    "input": "src/hero.png",
    "output": "dist/hero.webp",
    "format": "webp",
    "quality": 90
  },
  {
    "input": "https://cdn.example.com/avatar.png",
    "output": "assets/avatar.avif",
    "format": "avif",
    "width": 200,
    "height": 200
  },
  {
    "input": "photos/raw.jpg",
    "format": "jpeg",
    "quality": 75,
    "removeMetadata": true
  }
]

如果 output 如果省略,则文件将以新的扩展名写入输入旁边。

清单项目字段:

字段必填描述
input文件路径或HTTP/HTTPS URL
format目标格式
output输出文件路径。汽车衍生自 input 如果省略。
quality质量1–100,默认值 85
width以像素为单位调整宽度
height以像素为单位调整高度
removeMetadata删除EXIF元数据,默认值 false
# Process manifest, capture JSON results
img-convert batch jobs.json --json > results.json 2>/dev/null

# Process with human-readable progress
img-convert batch jobs.json -c 8

每个项目的JSON输出:

{
  "index": 0,
  "input": "src/hero.png",
  "output": "dist/hero.webp",
  "inputBytes": 512000,
  "outputBytes": 102400,
  "reduction": 80.0,
  "width": 1920,
  "height": 1080,
  "format": "webp",
  "quality": 90
}

______________________________________________________________________

mcp 子命令

在stdio上启动MCP(模型上下文协议)服务器。这是AI代理的主要集成点。

img-convert mcp

AI代理集成 了解全部细节。

______________________________________________________________________

AI代理集成

img-convert 被设计为由AI代理直接调用的原生类型工具,而不是原始shell命令。

MCP服务器

模型上下文协议 是为AI代理提供结构化工具访问的开放标准。 img-convert 运送生产就绪的MCP服务器。

使用克劳德代码注册

添加 ~/.claude/mcp.json:

{
  "mcpServers": {
    "img-convert": {
      "command": "img-convert",
      "args": ["mcp"]
    }
  }
}

注册后,Claude Code可以调用 convert_image, get_image_info, batch_convert,以及 list_supported_formats 作为原生工具——具有完整的类型检查、无shell转义和结构化返回值。

向其他MCP客户端注册

任何支持MCP stdio传输的客户端都可以正常工作。指向 img-convert mcp.

光标 (~/.cursor/mcp.json), 继续, 泽德,任何其他MCP主机遵循相同的模式:

{
  "mcpServers": {
    "img-convert": {
      "command": "img-convert",
      "args": ["mcp"]
    }
  }
}

MCP工具

convert_image

转换单个图像文件。接受文件路径和URL。

输入架构:

参数类型必填说明
input_pathstring文件路径或HTTP/HTTPS URL
output_formatstring以下之一: jpeg png webp avif gif tiff
output_pathstring输出文件路径。源自 input_path 如果省略,则使用新的扩展名。
qualitynumberNo质量1–100,默认值 85
widthnumber调整宽度,保持纵横比
heightnumber调整高度,保持纵横比
remove_metadataboolean删除EXIF,默认值 false
grayscaleboolean去饱和为灰度
rotatenumberNo旋转度
backgroundstring背景填充颜色(CSS颜色字符串)

退货:

{
  "input_path": "photo.jpg",
  "output_path": "photo.webp",
  "input_bytes": 204800,
  "output_bytes": 81920,
  "reduction": 60.0,
  "width": 1920,
  "height": 1080,
  "format": "webp",
  "quality": 85
}

get_image_info

无需转换即可获取图像的完整元数据。

输入架构:

参数类型必填说明
input_pathstring文件路径或HTTP/HTTPS URL

退货:

{
  "format": "jpeg",
  "width": 4032,
  "height": 3024,
  "filesize": 3891200,
  "hasAlpha": false,
  "hasExif": true,
  "colorSpace": "srgb",
  "isAnimated": false,
  "channels": 3,
  "density": 72
}

首先使用此选项做出明智的转换决策:图像是否具有透明度(影响JPEG转换),是否具有动画(影响帧处理),颜色空间是什么(影响打印工作流程)?

batch_convert

在一次工具调用中转换多个图像。

输入架构:

参数类型必填说明
itemsarrayYes转换作业数组(见下文)
concurrencynumberNo并行限制,默认值 4

中的每个项目 items:

字段类型必填
input_pathstring
output_formatstring
output_pathstring
quality编号
width编号
height编号

退货: 结果对象数组,每个输入项一个。

list_supported_formats

枚举服务器可以读取和写入的内容。

退货:

{
  "input": ["jpeg", "png", "webp", "avif", "gif", "tiff", "heic", "svg", "bmp"],
  "output": ["jpeg", "png", "webp", "avif", "gif", "tiff"]
}

JSON输出设计

每个命令都旨在生成可解析、可管道化的输出:

  • --json 旗帜:stdout上的数据为JSON,stderr上的所有进度/警告
  • info 子命令:总是JSON,不需要标志
  • batch --json:JSON数组,每个清单项有一个条目

这为代理和脚本提供了清晰的信号分离:

# Capture reduction percentage
REDUCTION=$(img-convert photo.jpg -f webp --json 2>/dev/null | jq .reduction)

# Inspect before converting
HAS_ALPHA=$(img-convert info logo.png | jq .hasAlpha)
if [ "$HAS_ALPHA" = "true" ]; then
  img-convert logo.png -f jpeg --background "#ffffff" --json 2>/dev/null
else
  img-convert logo.png -f jpeg --json 2>/dev/null
fi

# Count failed conversions in a batch
FAILED=$(img-convert batch jobs.json --json 2>/dev/null | jq '[.[] | select(.error)] | length')

清单批处理模式

AI代理自然地使用JSON作为数据格式。清单模式将作业定义与执行解耦——代理将作业列表组装为数据结构,将其写入文件,然后 img-convert batch 执行它:

// Agent builds the manifest
const manifest = imagePaths.map(inputPath => ({
  input: inputPath,
  output: inputPath.replace(/\.\w+$/, '.webp'),
  format: 'webp' as const,
  quality: 85,
}))

fs.writeFileSync('convert-jobs.json', JSON.stringify(manifest, null, 2))

// Agent executes it and reads structured results
const stdout = execSync('img-convert batch convert-jobs.json --json 2>/dev/null', {
  encoding: 'utf8',
})
const results = JSON.parse(stdout)
const totalSaved = results.reduce(
  (sum: number, r: { inputBytes: number; outputBytes: number }) =>
    sum + (r.inputBytes - r.outputBytes),
  0
)

没有shell插值,没有引用边缘情况,完全声明性,完全可审计。

______________________________________________________________________

Node.js API

import { convert, getInfo, batch } from '@dutchbase/img-convert'

这三个函数都接受文件路径、HTTP/HTTPS URL或原始文件 Buffer 对象作为输入。

convert()

function convert(
  input: string | Buffer,
  options: ConvertApiOptions
): Promise

ConvertApiOptions:

interface ConvertApiOptions {
  format: ImageFormat;           // required — "jpeg"|"png"|"webp"|"avif"|"gif"|"tiff"
  quality?: number;              // default 85
  width?: number;
  height?: number;
  removeMetadata?: boolean;      // default false
  maintainAspectRatio?: boolean; // default true
  allowUpscaling?: boolean;      // default false (prevents enlargement)
  crop?: {
    left: number;
    top: number;
    width: number;
    height: number;
  };
  rotate?: number;               // arbitrary degrees
  autoRotate?: boolean;          // apply and strip EXIF orientation tag
  flip?: boolean;                // horizontal mirror
  flop?: boolean;                // vertical mirror
  background?: string;           // CSS color string
  grayscale?: boolean;
  blur?: number;                 // Gaussian sigma 0.3–1000
  sharpen?: boolean;
  normalize?: boolean;
  trim?: boolean;
}

ConvertApiResult:

interface ConvertApiResult {
  buffer: Buffer;
  info: {
    inputBytes: number;
    outputBytes: number;
    width: number;
    height: number;
    format: string;
  };
}

示例:

import { convert } from '@dutchbase/img-convert'
import fs from 'fs/promises'

// Convert a local file
const result = await convert('./photo.jpg', {
  format: 'webp',
  quality: 85,
  width: 1280,
})
await fs.writeFile('./photo.webp', result.buffer)
console.log(`${result.info.inputBytes} → ${result.info.outputBytes} bytes`)

// Convert from a URL
const fromUrl = await convert('https://example.com/image.png', {
  format: 'avif',
  quality: 70,
})

// Convert from an in-memory Buffer (e.g. from a multipart upload handler)
const fromBuffer = await convert(req.file.buffer, {
  format: 'jpeg',
  quality: 90,
  background: '#ffffff',  // flatten PNG transparency before JPEG encoding
})

// Crop then resize
const cropped = await convert('./screenshot.png', {
  format: 'webp',
  crop: { left: 100, top: 50, width: 800, height: 600 },
  width: 400,
})

// Strip EXIF, rotate to EXIF orientation, then re-encode
const clean = await convert('./camera.jpg', {
  format: 'jpeg',
  autoRotate: true,
  removeMetadata: true,
  quality: 88,
})

getInfo()

function getInfo(input: string | Buffer): Promise
interface ImageInfo {
  format: string;
  width: number;
  height: number;
  filesize: number;
  hasAlpha: boolean;
  hasExif: boolean;
  colorSpace: string;
  isAnimated: boolean;
  channels?: number;
  density?: number;
}

示例:

import { getInfo, convert } from '@dutchbase/img-convert'

const info = await getInfo('./photo.jpg')
// { format: 'jpeg', width: 4032, height: 3024, filesize: 3891200,
//   hasAlpha: false, hasExif: true, colorSpace: 'srgb', isAnimated: false }

// Conditional conversion: don't flatten alpha if not needed
const { hasAlpha } = await getInfo('./image.png')
const result = await convert('./image.png', {
  format: 'jpeg',
  ...(hasAlpha ? { background: '#ffffff' } : {}),
})

// Skip animated GIFs in a batch
const infos = await Promise.all(paths.map(p => getInfo(p)))
const staticOnly = paths.filter((_, i) => !infos[i].isAnimated)

batch()

function batch(
  items: BatchApiItem[],
  options?: BatchApiOptions
): Promise
interface BatchApiItem {
  input: string;           // file path or URL
  output?: string;         // output file path — auto-derived if omitted
  format: ImageFormat;
  quality?: number;
  width?: number;
  height?: number;
  removeMetadata?: boolean;
}

interface BatchApiOptions {
  concurrency?: number;    // default 4
  outputDir?: string;      // write all outputs here when output not specified per-item
}

interface BatchApiResult {
  input: string;
  output: string;
  inputBytes: number;
  outputBytes: number;
  width: number;
  height: number;
  format: string;
  quality: number;
}

例子:

import { batch } from '@dutchbase/img-convert'

const results = await batch(
  [
    { input: './src/hero.png',   format: 'webp', quality: 90 },
    { input: './src/thumb.jpg',  format: 'avif', width: 200 },
    { input: './src/banner.gif', format: 'webp' },
  ],
  { concurrency: 4 }
)

for (const r of results) {
  const pct = ((1 - r.outputBytes / r.inputBytes) * 100).toFixed(1)
  console.log(`${r.input} → ${r.output} (${pct}% smaller)`)
}
// ./src/hero.png   → ./src/hero.webp   (67.3% smaller)
// ./src/thumb.jpg  → ./src/thumb.avif  (71.0% smaller)
// ./src/banner.gif → ./src/banner.webp (44.2% smaller)

______________________________________________________________________

REST API

web应用程序公开了一个端点。它可以直接从任何HTTP客户端调用。

POST /api/convert

接受 multipart/form-data。以二进制形式返回转换后的图像。

请求字段:

字段类型必填备注
file文件源图像。最大50 MB。
targetFormatstringjpeg png webp avif gif tiff
qualitystring整数1–100,默认值 85
resizeWidthstring目标宽度(像素)
resizeHeightstring目标高度(像素)
maintainAspectRatio"true"默认值 false
removeMetadata"true"删除EXIF,默认值 false
allowUpscaling"true"默认情况下允许放大 false

成功响应:

  • 状态: 200
  • 正文:原始图像字节
  • 标题:

- Content-Type --格式MIME类型 - Content-Disposition: attachment; filename="." - X-Output-Size --输出大小(字节(字符串)) - X-Output-Filename --经过净化的输出文件名

错误响应形状:

interface ApiErrorResponse {
  error: string;     // machine-readable error code
  message: string;   // human-readable description
  field?: string;    // which form field caused the error, if applicable
}

错误代码:

HTTP状态错误代码原因
400MISSING_FILE请求中没有文件
400MISSING_TARGET_FORMATtargetFormat 未提供
400UNSUPPORTED_TARGET_FORMAT仅输入请求的输出格式
400INVALID_QUALITY质量不是1到100之间的整数
400INVALID_DIMENSION宽度或高度不是正整数
413FILE_TOO_LARGE文件超过50 MB
415UNSUPPORTED_FORMAT魔术字节检查失败(声明MIME≠实际内容)
422IMAGE_TOO_LARGE像素尺寸超过2500万像素
422LIVE_PHOTO_NOT_SUPPORTED检测到HEIC实时照片
500CONVERSION_FAILED未处理的严重错误

卷曲示例:

curl -s -X POST http://localhost:3000/api/convert \
  -F "file=@photo.jpg" \
  -F "targetFormat=webp" \
  -F "quality=85" \
  -o output.webp

# Check output size from response header
curl -sI -X POST http://localhost:3000/api/convert \
  -F "file=@photo.jpg" \
  -F "targetFormat=webp" \
  | grep X-Output-Size

______________________________________________________________________

格式支持

输入格式

格式MIME类型注释
JPEGimage/jpeg
PNGimage/png支持透明度
WebPimage/webp支持动画WebP
AVIFimage/avif
GIFimage/gif支持GIF动画
TIFFimage/tiff
HEIC/HEIFimage/heic, image/heif, image/heic-sequence, image/heif-sequence通过预解码 heic-convert。每个文件增加约200-500毫秒。
SVGimage/svg+xml通过librsvg(夏普内置)进行光栅化。输出大小=SVG声明的尺寸,除非被覆盖 --width/--height.
BMPimage/bmp只读。夏普没有BMP输出编码器。

输出格式

格式质量标志典型用途
jpeg照片,无透明度要求
png压缩衍生无损、透明、截图
webp网络图像——大多数内容的最佳尺寸/质量权衡
avif文件最小,每字节质量最高。编码速度较慢。
gif动画图像
tiff打印工作流、存档存储

格式转换说明

透明度→ JPEG. JPEG没有alpha通道。没有 --background,透明像素变为黑色。总是通过 --background "#ffffff" (或您的目标填充颜色)将具有透明度的PNG/WebP/AVIF转换为JPEG时。

将GIF动画转换为静态格式。 将动态GIF转换为JPEG或PNG只会捕获第一帧。要保留动画,请转换为WebP(支持动画)。

SVG光栅化。 Sharp使用librsvg来光栅化SVG。默认光栅大小是SVG声明的 width/height 属性。通过 --width--height 以控制输出像素尺寸。

HEIC解码。 夏普无法直接解码苹果的HEIC格式。 img-convert 使用 heic-convert 库首先将HEIC解码为PNG缓冲区,然后将其传递给Sharp。这增加了延迟,并且每个文件都是单线程的。

PNG质量。 PNG是无损的,所以 --quality 控制夏普 compressionLevel (来源于 Math.round((100 - quality) / 11)).更高的质量=更低的压缩=更快的编码+更大的文件。无论哪种方式,图像数据都是相同的。

______________________________________________________________________

处理选项

管道按此固定顺序运行。每一步都是选择加入和独立的。

Input
  → HEIC pre-decode (if source is HEIC)
  → Decompression bomb guard (rejects > 25 megapixels)
  → Metadata handling (strip or preserve)
  → Auto-rotate / Rotate
  → Flip / Flop
  → Crop
  → Resize
  → Grayscale
  → Normalize
  → Blur
  → Sharpen
  → Trim
  → Background flatten (before JPEG encoding)
  → Format encode
  → Output
选项CLIAPI字段注释
质量--qualityquality1–100.适用于JPEG、WebP、AVIF、TIFF。
调整大小--width / --heightwidth / height符合尺寸要求。除非满足以下条件,否则不得升级 allowUpscaling: true.
元数据--no-metadataremoveMetadata剥离EXIF/XMP/IPTC。ICC档案始终保留。
作物--crop: { left, top, width, height }在调整大小之前运行。原始图像空间中的像素坐标。
自动旋转--autoRotate应用EXIF方向并剥离标签。
旋转--rotate rotate任何角度。空的角落充满了 background 颜色。
翻转--flipflip左-右后视镜。
Flop--flopflop顶部-底部镜子。
背景 --background backgroundCSS颜色字符串。用于旋转角点和JPEG展平。
灰度--grayscalegrayscale去饱和为单个亮度通道。
模糊--blur blur高斯模糊,西格玛0.3-1000。
锐化--sharpensharpen使用Sharp默认值取消锐化蒙版。
正常化--normalizenormalize将直方图拉伸到全范围。
修剪--trimtrim删除均匀颜色边缘像素。

______________________________________________________________________

建筑

img-convert/
├── cli/
│   ├── index.ts           # Commander CLI — convert, info, batch, mcp subcommands
│   ├── helpers.ts         # Pure functions: path building, format detection, option mapping
│   └── mcp.ts             # MCP server — registers tools, handles stdio transport
├── lib/
│   ├── imageProcessor.ts  # Core Sharp pipeline — single source of truth for all interfaces
│   ├── api.ts             # Programmatic Node.js API: convert(), getInfo(), batch()
│   ├── heicDecoder.ts     # HEIC → PNG buffer pre-decode step
│   └── processingQueue.ts # Concurrency semaphore for the REST endpoint
├── types/
│   ├── index.ts           # Shared types: ImageFormat, ConvertOptions, API types
│   └── client.ts          # Browser-safe re-export + MIME → ImageFormat detection helper
├── app/
│   ├── api/convert/
│   │   └── route.ts       # Next.js Route Handler: POST /api/convert
│   ├── layout.tsx
│   └── page.tsx
├── components/
│   ├── ImageConverter.tsx # Top-level stateful client component
│   ├── DropZone.tsx       # Drag-and-drop file input
│   ├── ConvertOptions.tsx # Format selector, quality slider, resize controls
│   ├── ConvertResult.tsx  # Download link + size comparison
│   ├── BatchQueue.tsx     # Multi-file batch UI with per-item status
│   └── ImagePreview.tsx   # Source image preview
├── dist/
│   └── cli/               # Compiled CLI output (CommonJS, aliases resolved by tsc-alias)
└── __tests__/
    ├── imageProcessor.test.ts
    ├── cli.test.ts
    ├── route.test.ts
    ├── batchQueue.test.ts
    └── ...

单管路,四个接口

processImage() 函数 lib/imageProcessor.ts 是夏普的标准管道。它被称为:

  1. 命令行界面 (cli/index.ts)--读取文件或stdin,写入磁盘
  2. Node.js API (lib/api.ts)--用输入分辨率和结构化结果对象包装processImage
  3. REST API (app/api/convert/route.ts)--验证多部分表单字段并返回二进制HTTP响应
  4. MCP服务器 (cli/mcp.ts)--将工具调用参数转换为processImage选项,写入文件,返回JSON

所有四个接口对相同的输入产生相同的输出。任何接口都没有单独的代码路径。

并发模型

接口机制默认限制
CLIp-limit 每次调用--concurrency 4
Node.js APIp-limitbatch() 呼叫options.concurrency ?? 4
REST APIasync-sema 所有请求的信号量processingQueue (1个插槽)
MCP批次p-limitbatch_convert 呼叫concurrency ?? 4

REST端点的信号量是有意保守的(单槽),以防止并发浏览器请求下的内存耗尽。CLI和API并发是用户控制的。

构建系统

配置目的
tsconfig.jsonNext.js应用程序-- moduleResolution: "bundler", noEmit: true
tsconfig.cli.jsonCLI+API- moduleResolution: "node", module: "CommonJS",发射到 dist/cli/
tsc-alias后处理编译JS进行重写 @/* 相对路径的路径别名

两个tsconfig方法是有意的:Next.js bundler处理模块解析的方式与Node.js require()不同。共享一个配置需要在两个方向上做出妥协。

______________________________________________________________________

发展

设置

git clone https://github.com/dutchbase/img-convert
cd img-convert
npm install

命令

npm run dev            # Start Next.js dev server at http://localhost:3000
npm run build          # Production Next.js build + type-check
npm run build:cli      # Compile CLI + API to dist/cli/ (required before running img-convert locally)
npm run lint           # ESLint
npm test               # Jest unit tests
npm run test:coverage  # Jest with coverage report
npm run test:e2e       # Playwright end-to-end tests
npm run test:all       # Unit + E2E

添加新的输出格式

  1. 将格式密钥添加到 ImageFormat 工会 types/index.ts
  2. 将条目添加到 FORMAT_LABELS, FORMAT_MIME, FORMAT_EXTENSIONS
  3. 将格式添加到 OUTPUT_FORMATS (或 INPUT_ONLY_FORMATS 如果Sharp无法对其进行编码)
  4. 将案例添加到 applyFormat()lib/imageProcessor.ts
  5. 将MIME类型添加到 detectFormat()lib/imageProcessor.ts
  6. 将MIME类型添加到 detectFormatFromMime()types/client.ts
  7. 将扩展名添加到 EXT_TO_FORMATcli/helpers.ts
  8. 将MIME类型添加到 accept 属性于 components/DropZone.tsx

添加新的处理选项

  1. 将字段添加到 ConvertOptionstypes/index.ts
  2. 添加 ConvertApiOptionstypes/index.ts 如果它应该是公共API的一部分
  3. 申请 lib/imageProcessor.ts 在正确的管道位置
  4. 将CLI标志添加到 programcli/index.ts
  5. 电线穿过 buildConvertOptions()cli/helpers.ts
  6. 暴露在MCP中 convert_image 中的工具输入模式 cli/mcp.ts
  7. 在中添加UI控件 components/ConvertOptions.tsx 如果它应该在web UI中

测试结构

现场测试 __tests__/ 和杰斯特一起跑+ ts-jest。测试环境是按中的每个文件配置的 jest.config.ts:

  • 节点环境: imageProcessor.test.ts, route.test.ts, cli.test.ts, heicDecoder.test.ts, animatedGif.test.ts
  • JSDOM环境: imageConverter.test.tsx, dropZone.test.ts, batchQueue.test.ts, processingQueue.test.ts

Sharp操作在测试中使用实际的Sharp库(无模拟),并在 __tests__/fixtures/.

安全注意事项

REST端点应用了多个防御层:

  1. 文件大小限制 --读取正文前使用50 MB硬盖
  2. MIME分配列表 --源格式必须是可识别的图像类型
  3. 魔术字节验证file-type 检查实际文件内容,而不仅仅是浏览器提供的MIME标头
  4. 像素尺寸检查 --在分配解码缓冲区之前,拒绝超过2500万像素的图像
  5. 急剧减压极限limitInputPixels: 25_000_000 传递给每个夏普制造商
  6. 文件名清理Content-Disposition 文件名中除以下字符外的所有字符都被删除 [a-zA-Z0-9._-]

CI/CD

.github/workflows/ci.yml 在每次推送和公关中运行:

  • 节点18、20和22的测试
  • npm test, npm run build, npm run build:cli
  • 验证编译后的CLI二进制文件是否正确执行

.github/workflows/release.yml 触发器打开 v* 标签:

  • 运行完整的测试套件
  • 构建CLI
  • 发布到npm 来源证明
# Publish a new release
npm version patch    # or minor / major
git push --follow-tags
# GitHub Actions handles the rest

______________________________________________________________________

贡献

欢迎拉取请求。

  1. 首先打开一个问题,进行非琐碎的更改。
  2. 保持 processImage() 作为单个管道-不要在CLI、API、REST和MCP之间分叉处理逻辑。
  3. 维护stderr/ststdout合约:stdout上的数据,stderr上的进度。 --json 应始终生成可解析的输出。
  4. 添加新功能和错误修复的测试。测试套件应保持绿色 npm test.
  5. npm test && npm run build:cli 在提交之前。

______________________________________________________________________

许可证

麻省理工学院

目录标签

目录标签

图像处理多平台支持TypeScriptClaude格式转换本地部署开发工具AI集成

支持客户端

ClaudeCursor

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

none

运行时(runtime,运行环境)

Node.js

来源包(packageName,安装包名)

@dutchbase/img-convert

工具数量(toolCount,工具数)

4

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdionone部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP