关于 homotope
homotope 是一个用 TypeScript 编写的引擎,可将栅格图像转换为矢量图形及制造格式。它面向需要可配置描摹、保留形状拓扑并检查切割就绪状态的开发者和制造工作流。
主要功能
- 01将栅格图像转换为 SVG
- 02将 SVG 导出为 DXF、PDF 或 EPS
- 03保留共享边界和孔洞
- 04提供图像与线稿预设
- 05检查 SVG 切割就绪状态
适用场景
- 01将徽标描摹为矢量路径
- 02为绘图仪或雕刻准备图稿
- 03切割前检查 DXF 几何
MCP 相关
README 提到托管版 homotope.app 提供 MCP 服务,但未说明该服务的工具或能力。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://homotope.app/mcpclaude mcp add --transport http app-homotope-homotope https://homotope.app/mcp{"mcpServers":{"app-homotope-homotope":{"type":"http","url":"https://homotope.app/mcp"}}}在 Cursor 中打开{"servers":{"app-homotope-homotope":{"type":"http","url":"https://homotope.app/mcp"}}}在 VS Code 中打开{"mcpServers":{"app-homotope-homotope":{"type":"http","url":"https://homotope.app/mcp"}}}{"mcpServers":{"app-homotope-homotope":{"serverUrl":"https://homotope.app/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
@homotope/engine
纯 TypeScript 栅格转矢量引擎:可将 PNG 或 JPEG(任意 RGBA 像素缓冲区)转换为简洁的 SVG,再将 SVG 转换为 DXF、PDF 或 EPS。它是在线图像矢量化工具 Homotope 背后的引擎,采用 MIT 许可证发布。
- 无 DOM,无运行时依赖。 核心代码可直接运行于 Web Worker、主线程和 Node。像素数据始终留在本机:不会上传到任何地方。
- 拓扑优先。 图像在 OKLab 中量化并分割为多个区域,每条共用边界都只拟合一次:相邻形状绝不会重叠或留有间隙。保留孔洞(「O」仍然是「O」)。
- 提供适用于徽标、插画、像素艺术、线稿、黑白图像和照片的预设,以及将笔画描摹为单条开放路径的中心线模式(适用于绘图仪、雕刻和刺绣)。
- 制造导出: DXF(每种颜色一个图层,共用边只切割一次)、PDF、EPS、颜色分版,以及切割就绪检查(微小孤岛、过近的边缘、节点数量)。
- Potrace 的替代方案:不含 GPL 代码、支持全彩、边界精确共用。
安装
npm install @homotope/engine
# Node only, to decode PNG/JPEG files (optional peer dependencies):
npm install pngjs jpeg-js
需要 ES2022 运行时(Node ≥ 22,或任意当前版本的浏览器)。仅支持 ESM。
入口点
| 导入 | 内容 | 依赖项 |
|---|---|---|
@homotope/engine | vectorize、presetOptions、PRESET_NAMES、所有类型 | 无 |
@homotope/engine/export | convertSvg(SVG → PDF、DXF、EPS)、exportLayers、sceneFromSvg | 无 |
@homotope/engine/cutcheck | checkSvg、simplifySvg:适用于切割机的切割就绪报告 | 无 |
@homotope/engine/node | decodePng、decodeJpeg、encodePng、encodeJpeg | pngjs、jpeg-js |
浏览器包只会包含导入的内容:核心代码绝不会导入 pngjs 或 jpeg-js。
Node 示例
import { readFileSync, writeFileSync } from 'node:fs';
import { vectorize, presetOptions } from '@homotope/engine';
import { convertSvg } from '@homotope/engine/export';
import { decodePng } from '@homotope/engine/node';
const image = decodePng(new Uint8Array(readFileSync('logo.png')));
const result = vectorize(image, presetOptions('logo'), {
onProgress: (e) => process.stdout.write(`\r${e.stage} ${Math.round(e.progress * 100)}%`),
});
writeFileSync('logo.svg', result.svg);
writeFileSync('logo.dxf', convertSvg(result.svg, 'dxf'));
console.log(`\n${result.palette.colors.length} colours, ${result.stats.paths} paths`);
浏览器示例(Web Worker)
vectorize 有意设计为同步函数:请在 worker 中运行,以保持页面响应流畅。其输入可以是任意类似 ImageData 的对象 { width, height, data: Uint8ClampedArray }(RGBA,非预乘)。
// main.ts
const bitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
const ctx = canvas.getContext('2d')!;
ctx.drawImage(bitmap, 0, 0);
const { width, height, data } = ctx.getImageData(0, 0, bitmap.width, bitmap.height);
const worker = new Worker(new URL('./vectorize.worker.ts', import.meta.url), { type: 'module' });
worker.onmessage = (e: MessageEvent<{ svg: string }>) => {
const url = URL.createObjectURL(new Blob([e.data.svg], { type: 'image/svg+xml' }));
document.querySelector<HTMLImageElement>('#preview')!.src = url; // or offer it as a download
};
worker.postMessage({ width, height, data }, [data.buffer]);
// vectorize.worker.ts
import { vectorize, presetOptions, type RasterImage } from '@homotope/engine';
self.onmessage = (e: MessageEvent<RasterImage>) => {
const { svg } = vectorize(e.data, presetOptions('illustration'));
self.postMessage({ svg });
};
取消采用协作式机制:将 { cancel: { cancelled: boolean } } 作为第三个参数传入(例如使用 SharedArrayBuffer 作为底层支持);随后 vectorize 会在各个阶段之间及阶段内部抛出 CancelledError。
预设
presetOptions(name) 会返回一个完整且独立的选项对象,你可以对其进行调整。
| 预设 | 用途 |
|---|---|
logo | 平面色彩、清晰的拐角、保持直线笔直 |
illustration | 最多 32 种颜色、更平滑的曲线、轻微渐变、形状叠加 |
pixel-art | 精确的像素网格、无曲线、零误差 |
line-art | 墨水画和文本:两种颜色、填充形状 |
centerline | 将笔画描摹为单条开放路径(绘图仪、激光雕刻) |
black-white | 通过自动(Otsu)阈值生成两种颜色 |
photo | 最多 64 种颜色、降噪、合并小区域、形状叠加 |
import { presetOptions, vectorize } from '@homotope/engine';
const options = presetOptions('logo');
options.quantize.colors = 4; // fixed number of colours instead of 'auto'
options.export.precision = 1; // decimals in path data
options.export.mode = 'stacked'; // fewer nodes: shapes stacked instead of cut out
const { svg } = vectorize(image, options);
每个选项都有类型定义和文档,详见 VectorizeOptions(preprocess、quantize、segment、fit、export、centerline)。
SVG 输出
viewBox使用原始图像的像素坐标,采用三次贝塞尔曲线,默认每种颜色对应一个<path>(export.mergeByColor)。export.mode: 'cut'(默认):每个区域都是带孔洞的精确路径(fill-rule="evenodd"),彼此不重叠;'stacked':按深度堆叠形状,节点更少。- 透明像素(
preprocess.alphaMode: 'keep')不会生成路径。 result.palette列出颜色(sRGB 和 OKLab,以及像素数);result.stats列出路径数和节点数;result.timings列出各阶段耗时。
托管版本和 API
homotope.app 在浏览器中运行此引擎,提供可视化编辑器(调色板、预设、前后对比),还提供可选的服务器端处理、REST API 和面向 AI 助手的 MCP 服务:请参阅 API 文档。
开发
npm install
npm test # Vitest, no DOM
npm run typecheck
npm run lint
npm run eval # renders every fixture and measures the error (Resvg)
npm run build # dist/ (ESM + .d.ts)
请参阅 CONTRIBUTING.md。
许可证
MIT。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。