Vectorize
Converta imagens raster para SVG, EPS, PDF ou DXF, com predefinições e controle por opção. Sem estado.
Documentação
API vectorize v0.4.8
Conversão de raster → vetor via HTTP. Cada requisição é stateless; nada é armazenado.
Endpoints
| Método | Caminho | Descrição |
|---|---|---|
| POST | /api/v1/trace | Converte uma imagem. Corpo: multipart/form-data com campo image (e options JSON opcional), ou bytes brutos da imagem com um tipo de conteúdo image/*, ou JSON {"image": "<base64>", "options": {…}}. Query: format=svg|eps|pdf|dxf|json, dpi, unit=px|mm|cm|in|pt, width, além de qualquer opção abaixo. |
| GET | /api/v1/options | Presets, metadados de opções, formatos de saída e input — os formatos de imagem que esta build decodifica, com seus tipos de mídia e extensões. |
| GET | /api/v1/usage | Uso de hoje e cota restante da chave chamadora. |
| GET | /healthz | Liveness, profundidade da fila, workers. |
| GET | /metrics | Métricas Prometheus, protegidas pela mesma chave de API. |
Autenticação: obrigatória — esta API requer uma conta. Entre ou crie uma, crie uma chave de API para Vectorize lá e envie-a como X-Api-Key: ak_… (ou um token de acesso como Authorization: Bearer). Toda conta começa com uma cota gratuita de traces; GET /api/v1/usage informa o que resta, assim como os cabeçalhos X-Usage-Plan, X-Usage-Used, X-Usage-Limit e X-Usage-Remaining em cada resposta, com X-Usage-Reset em um plano mensal para o momento em que o contador reinicia. Um plano esgotado responde 402 com upgradeUrl.
Cabeçalhos de resposta: X-Vectorize-Paths, X-Vectorize-Colors, X-Vectorize-Ms, X-Vectorize-Upscale, X-Vectorize-Downscale. Erros são JSON {"error": "…"} com 400 (opção inválida), 401, 402 (plano esgotado), 413 (muito grande), 415 (formato não decodificável por esta build), 422 (não decodificável), 429, 503 (ocupado).
Formatos de imagem aceitos: PNG, JPEG, WebP, GIF, BMP. Qualquer outra coisa responde 415 nomeando o formato que era — HEIF/HEIC em particular, que é o que uma câmera de iPhone grava por padrão e para o qual a API não tem decodificador. O aplicativo web converte esses porque um navegador os decodifica com o decodificador do próprio sistema operacional e entrega pixels; a API só tem o que está compilado nela. Converta para JPEG ou PNG primeiro.
Limites desta instância: uploads de até 20 MB, respondidos com 413, e tracing de até 10 megapixels. Uma imagem maior não é recusada: ela é reduzida para esse teto, traçada lá e desenhada em tamanho total — uma foto de celular ou um scan de 600 dpi não carrega detalhe que um tracer possa usar além desse ponto — e X-Vectorize-Downscale informa por quanto. Um upscale de preset que não caberia é reduzido da mesma forma, relatado em X-Vectorize-Upscale. Apenas uma imagem mais de doze vezes o teto é recusada com 413, antes de ser decodificada.
Exemplos
curl -X POST 'https://vectorize-api.dudko.dev/api/v1/trace?preset=photo&maxColors=16&format=svg' \
-H 'X-Api-Key: KEY' -F [email protected] -o photo.svg
curl -X POST 'https://vectorize-api.dudko.dev/api/v1/trace?format=pdf&dpi=300' \
-H 'X-Api-Key: KEY' -H 'Content-Type: image/png' --data-binary @logo.png -o logo.pdf
curl -X POST 'https://vectorize-api.dudko.dev/api/v1/trace?format=json&preset=poster&text=trace' \
-H 'X-Api-Key: KEY' -F [email protected] -F 'options={"maxColors":8,"transparentBackground":true}'
Experimente
Para um assistente
Um endpoint MCP em https://vectorize-api.dudko.dev/mcp é a porta de entrada para esta API para um assistente: api_access explica como a API funciona, trace_options lista os presets e opções, e api_request verifica as opções e retorna a requisição exata com uma credencial de curta duração para a conta conectada. Nenhuma imagem passa por ele. Aponte um cliente MCP para esse endereço; ele encontra o resto — qual servidor de autorização emite os tokens e qual escopo pedir — em https://vectorize-api.dudko.dev/.well-known/oauth-protected-resource/mcp. Um token é aceito somente se foi emitido para este endereço e nenhum outro.
Opções
Todas opcionais; opções não definidas caem para o preset. Enumerações: preset bw|poster|photo, mode color|binary, layering shared|stacked|cutout, curveMode spline|polygon|pixel, strokeMode fill|centerline, text off|trace|raster; booleanos transparentBackground, adaptiveThreshold, gradients, salientColors; palette é uma lista separada por vírgulas de #rrggbb.
| Opção | Faixa | Significado |
|---|---|---|
superpixels | 0–32 px | Agrupa pixels vizinhos semelhantes antes da coloração. Suaviza ruído de foto e bandas de gradiente; muito grande desfoca pequenos detalhes. |
smooth | 0–10 | Suavização que preserva bordas da fonte. Achata ruído de sensor e blocos JPEG mantendo bordas reais. |
denoise | 0–5 passadas | Passadas de filtro mediano. Remove pontos isolados e ruído "mosquito" JPEG ao redor de bordas. |
cleanEdges | 0–4 passadas | Remove halos de um pixel entre áreas deixados por anti-aliasing. Desligue se linhas finas desaparecerem. |
gapFill | 0–2 px | Traça cada forma em sua própria cor para esconder costuras finas que alguns renderizadores mostram entre vizinhos. |
upscale | 1–4 × | Amplia a fonte antes do tracing. Curvas mais suaves em imagens pequenas com anti-aliasing; mais lento em grandes. Reduzido automaticamente quando a imagem ampliada não caberia no teto de pixels, em vez de a imagem ser recusada. |
maxColors | 0–64 | Número de cores na paleta. Menos cores = mais chapado, arquivo menor; mais = mais próximo do original. |
filterSpeckle | 0–128 px² | Ignora patches menores que esse número de pixels (comprimento do lado). Maior = mais limpo, mas descarta pequenos detalhes. No modo preto e branco, pontos e pontuação que ficam em uma linha de texto são mantidos mesmo quando menores. |
colorPrecision | 1–8 bits | Bits de cor mantidos ao agrupar sem paleta. Menor mescla cores semelhantes. |
layerDifference | 0–128 | Distância mínima de cor entre camadas ao agrupar sem paleta. |
cornerThreshold | 0–180 ° | Ângulo acima do qual uma dobra vira um canto agudo em vez de uma curva suave. |
lengthThreshold | 3,5–10 px | Comprimento mínimo de segmento ao ajustar splines. Maior = menos curvas, mais longas. |
spliceThreshold | 0–180 ° | Ângulo abaixo do qual dois segmentos são unidos em uma curva. |
pathPrecision | 0–4 decimais | Casas decimais escritas para coordenadas. Menos = arquivo menor, ligeiramente menos exato. |
threshold | 0–255 | Corte de luminância para preto e branco. Menor mantém apenas pixels escuros; maior mantém mais. |
paletteMerge | 0–20 ΔE | Mescla cores de paleta mais próximas que este ΔE para que uma imagem de 5 cores não receba 24 quase-duplicatas. |
strokeWidth | 0–20 px | Largura fixa para traços de linha central; "measured" usa a espessura própria de cada traço. |
gradientTolerance | 1–20 | O quanto uma sequência de faixas de cor pode desviar de uma rampa de cor reta e ainda virar um gradiente. |
Presets
| Preset | Opções efetivas |
|---|---|
bw | {"mode":"binary","layering":"stacked","curveMode":"spline","denoise":0,"smooth":0,"upscale":2,"maxColors":0,"cleanEdges":0,"gapFill":0,"transparentBackground":false,"superpixels":0,"adaptiveThreshold":true,"paletteMerge":6,"strokeMode":"fill","strokeWidth":0,"gradients":false,"gradientTolerance":6,"salientColors":false,"text":"off","filterSpeckle":4,"colorPrecision":6,"layerDifference":16,"cornerThreshold":60,"lengthThreshold":4,"spliceThreshold":45,"maxIterations":10,"pathPrecision":2,"threshold":128} |
poster | {"mode":"color","layering":"shared","curveMode":"spline","denoise":0,"smooth":0,"upscale":1,"maxColors":16,"cleanEdges":1,"gapFill":0.5,"transparentBackground":false,"superpixels":0,"adaptiveThreshold":false,"paletteMerge":6,"strokeMode":"fill","strokeWidth":0,"gradients":true,"gradientTolerance":6,"salientColors":true,"text":"trace","filterSpeckle":4,"colorPrecision":8,"layerDifference":16,"cornerThreshold":60,"lengthThreshold":4,"spliceThreshold":45,"maxIterations":10,"pathPrecision":2,"threshold":128} |
photo | {"mode":"color","layering":"shared","curveMode":"spline","denoise":1,"smooth":3,"upscale":1,"maxColors":24,"cleanEdges":1,"gapFill":0.5,"transparentBackground":false,"superpixels":8,"adaptiveThreshold":false,"paletteMerge":4,"strokeMode":"fill","strokeWidth":0,"gradients":true,"gradientTolerance":8,"salientColors":true,"text":"off","filterSpeckle":8,"colorPrecision":8,"layerDifference":48,"cornerThreshold":180,"lengthThreshold":4,"spliceThreshold":45,"maxIterations":10,"pathPrecision":2,"threshold":128} |