
Homotope 发布 MIT 许可的浏览器图像矢量化引擎,已上线 NPM
来源标题:Show HN: Homotope, vectorize images to SVG in the browser, MIT engine on NPM
Homotope 将其浏览器端图像矢量化引擎以 MIT 许可发布到 NPM,图像无需上传即可在浏览器内转换为 SVG。该引擎用纯 TypeScript 编写,可将 PNG/JPEG 转为 SVG,再导出为 DXF、PDF 或 EPS;npm 包版本冻结在 0.2.0。
以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
这是 Homotope 的引擎,一个在浏览器中运行的图像矢量化工具:不上传任何内容。你可以在 workshop 中试用(免费,SVG 和 PNG 无需账号)。
纯 TypeScript 实现的位图转矢量引擎:将 PNG 或 JPEG(任意 RGBA 像素缓冲区)转换为干净的 SVG,再从该 SVG 转换为 DXF、PDF 或 EPS。基于 MIT 许可证发布。
这个包不是什么:它没有编辑器、没有服务器、没有 REST API、没有 MCP server,也不做打印机检查;这些都在托管服务中。npm 包冻结在 0.2.0:其内容完整且可独立使用。
npm install @homotope/engine
仅 Node 环境,用于解码 PNG/JPEG 文件(可选 peer 依赖):
npm install pngjs jpeg-js
需要 ES2022 运行时(Node ≥ 22,任何当前浏览器)。仅支持 ESM。
导入 功能 依赖
vectorize、presetOptions、PRESET_NAMES、所有类型 无
convertSvg(SVG → PDF、DXF、EPS)、exportLayers、sceneFromSvg 无
checkSvg、simplifySvg:面向切割机的切割就绪报告 无
decodePng、decodeJpeg、encodePng、encodeJpeg pngjs、jpeg-js
浏览器打包产物只接收其导入的内容:核心从不导入 pngjs 或 jpeg-js。
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 有意设计为同步执行:请在工作线程中运行它,以保持页面响应。其输入是任何类似 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; // 或将其作为下载提供 }; 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) 返回一个完整、独立的选项对象,你可以自行调整。
import { presetOptions, vectorize } from '@homotope/engine';
const options = presetOptions('logo'); options.quantize.colors = 4; // 固定颜色数量,而非 'auto' options.export.precision = 1; // 路径数据中的小数位数 options.export.mode = 'stacked'; // 更少节点:形状堆叠而非挖空
const { svg } = vectorize(image, options);
每个选项都在 VectorizeOptions 中有类型定义和文档说明(preprocess、quantize、segment、fit、export、centerline)。
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 server:参见 API 文档。
npm install npm test # Vitest,无 DOM npm run typecheck npm run lint npm run eval # 渲染每个 fixture 并测量误差(Resvg) npm run build # dist/(ESM + .d.ts)
参见 CONTRIBUTING.md。
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。