homotope について
homotopeは、ラスター画像をベクター画像や製作用フォーマットに変換するTypeScriptエンジンです。設定可能なトレース、形状トポロジーの保持、加工前のチェックを必要とする開発者や製作ワークフロー向けです。
主な機能
- 01ラスター画像をSVGに変換
- 02SVGをDXF、PDF、EPSに出力
- 03共有境界と穴を保持
- 04画像や線画向けのプリセット
- 05SVGの切断準備状態を確認
活用シーン
- 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 を生成します。MIT ライセンスで公開されているオンライン画像ベクター化ツール、Homotope のエンジンです。
- 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 は意図的に同期処理になっています。ページの応答性を保つため、ワーカーで実行してください。入力には任意の 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 });
};
キャンセルは協調的に行われます。第 3 引数に { cancel: { cancelled: boolean } } を渡すと(たとえば SharedArrayBuffer を使って値を管理できます)、vectorize は各ステージの間およびステージ内で CancelledError をスローします。
プリセット
presetOptions(name) は、調整可能な独立した完全なオプションオブジェクトを返します。
| プリセット | 用途 |
|---|---|
logo | ベタ塗りの色、くっきりした角、直線は直線のまま保持 |
illustration | 最大 32 色、滑らかな曲線、淡いグラデーション、図形の重ね合わせ |
pixel-art | 正確なピクセルグリッド、曲線なし、誤差ゼロ |
line-art | インク画とテキスト向け:2 色、塗りつぶされた図形 |
centerline | ストロークを単一の開いたパスとしてトレース(プロッター、レーザー彫刻) |
black-white | 自動(Otsu)しきい値による 2 色 |
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、3 次ベジェ曲線、デフォルトでは色ごとに 1 つの<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 サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。