返回资讯中心
外部精选
软件工程
#开发者实时流

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。

Hacker News 最新sroman912026/11/4 · 5 天前12 分钟阅读

以下正文由 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 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →