Skip to content

Latest commit

 

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LogoTrace

Flat logo raster → RGB vector PDF tracer.
Drop a JPEG/PNG, get a clean PDF ready for print and Illustrator.

Pipeline: upscale (auto) → background detection (always kept) → unified auto palette → remap → VTracer spline → PDF


Quick start

cd /srv/hermes/projects/logotrace

# Development environment (the deployed one is built by deploy/live-venv.sh)
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt

# CLI
PYTHONPATH=. .venv/bin/python -m src.cli input/logo.jpg -o output/logo.pdf

# CLI with upscale off (escape hatch)
PYTHONPATH=. LOGOTRACE_UPSCALE=off .venv/bin/python -m src.cli input/logo.jpg -o output/logo.pdf

# API — the deployed instance listens on 127.0.0.1:8302 behind nginx
curl -s -F file=@input/logo.jpg -F palette=auto http://127.0.0.1:8302/vectorize -o out.pdf

Web UI: https://trace.idealabs.dev/ — paste/drop, Auto|1–8 colors, canvas preview + zoom/pan.

Deploy note: the service runs on mainframe as site-trace (port 8302); the live tree is /srv/sites/trace and is only ever written by the hosting script. One command does the whole deploy — mirror the tree, rebuild the virtualenv (sync deletes what the repository does not contain), restart, check health:

bash deploy/deploy.sh

Architecture

Raster (JPEG/PNG)
  │
  ├─ [src/pipeline.py]     upscale preprocess (default: auto toward 3072px cap)
  │   └─ Lanczos resize, effective factor ≤ 2x, skip if < 1.05x,
  │      pixel-unit VTracer thresholds scaled by effective factor
  │
  ├─ [src/colors.py]      unified auto palette (ADR-22/23)
  │   ├─ estimate_background()    bg detected, ALWAYS kept as bottom layer
  │   ├─ mass filter              clusters ≥ 3% of dominant
  │   ├─ weighted-HSL merge       w_L=2 w_S=1 w_H=1, thr 0.18 — never hue-only
  │   ├─ N = survivors, 1..8      (auto mode)
  │   └─ gradient crush           mass anchor; cannot drop mass colors;
  │                               bimodal guard kept as safety net
  │
  ├─ [src/preprocess.py]   brand-color remap
  │   └─ remap_to_palette()   snap pixels to measured colors (bg incl.)
  │
  ├─ [src/tracer_vtracer.py]  subprocess → VTracer 0.6.4
  │   └─ spline mode, color, mild speckle
  │
  ├─ [src/postprocess.py]  svgo optimize
  │
  ├─ [src/geometry.py]     path simplify (off by default, experimental — ADR-14)
  │
  ├─ [src/pdf_export.py]   SVG → PDF (rsvg-convert / cairosvg)
  │
  ├─ [src/verify.py]       self-check: raster output, assert non-blank
  │
  ├─ [src/pipeline.py]     orchestrator: vectorize_file / vectorize_bytes
  │
  ├─ [src/debug_save.py]   persist input/ui_* + output/ui_* + last.*
  │
  ├─ [src/api.py]          FastAPI: POST /vectorize, GET /health, static UI
  ├─ [src/cli.py]          Typer: --colors, --colors-mode, --geom, --format
  └─ [src/config.py]       VTracer binary path, thresholds

Palette = Auto / Manual K

palette Mode Behavior
auto auto-N bg + N inks, N = mass/HSL survivors, 1..8 (ADR-23)
1–16 exact K bg + exactly K inks by mass, no crush

Background occupies a reserved slot outside the ink limit (ADR-22). Response headers: X-LogoTrace-Colors, X-LogoTrace-Colors-Mode.

Geometry post-pass

--geom off (default) keeps raw VTracer splines. basic/strict are experimental and may facet curves. A separate geometry_fit refinement pass was built, benchmarked and removed (no visible benefit — ADR-21).


Evaluation

python -m src.eval input/ --colors 4

Canonical sample set: input/sample_01..sample_11. Metrics: area-weighted IoU (background is a first-class mask class), Chamfer on color-transition edges, nodes, SVG size. The log prints both iou_mean and iou_aw; iou_aw is the quality aggregate — see docs/EVAL-BASELINE.md. Pixel metrics are blind to smoothness and palette semantics — owner visual review is part of acceptance for palette/curve changes.


Project structure

logotrace/
  bin/vtracer                  # bundled 0.6.4 Linux x86_64
  src/
    api.py, cli.py, config.py
    colors.py                  # unified auto palette (ADR-22/23)
    preprocess.py, tracer_vtracer.py, pipeline.py
    pdf_export.py, postprocess.py, geometry.py
    verify.py, debug_save.py, disks.py
    eval.py                    # benchmark harness
  static/                      # Web UI (html/css/js + pdf.js)
  tests/                       # pytest
  docs/                        # STATUS, PRODUCT, PLAN, DECISIONS, PITFALLS + SPEC, EVAL-BASELINE, QA-NOTES
  deploy/                      # live-venv.sh (builds the service venv in the live tree) + nginx snippet
  input/                       # sample_01..sample_11 + ui_* debug dumps
  output/                      # gitignored PDFs/SVGs

The live copy lives at /srv/sites/trace and belongs to site-trace; only hermes-site-ctl sync writes there. The service virtualenv is built inside it by deploy/deploy.sh, because the service account cannot read /srv/hermes — see docs/PITFALLS.md.


CLI reference

# auto (default): auto-N palette (ADR-23)
python -m src.cli input.jpg -o out.pdf

# manual exact K: no crush — dual gray survives
python -m src.cli input/sample_05.jpg -o out.pdf -c 2 --colors-mode exact

# debug SVG path geometry
python -m src.cli input.jpg -o out.svg --format svg

API

POST /vectorize
  file=@logo.jpg    (multipart, required)
  palette=auto|1-16 (default auto; UI exposes 1-8)
  format=pdf|svg    (default pdf)

GET  /health
GET  /              (Web UI)

Documentation


License

GPL-3.0-or-later. See LICENSE and NOTICE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages