Paste a messy logo. Get a DXF that EZCAD fills cleanly.
A black-and-white image vectorizer built for fiber laser marking shops — EZCAD2/3, JCZ galvo controllers, LightBurn. Not a drawing program, not a general-purpose tracer: every default exists because of something that goes wrong on the machine.
What it's for · Why not Image Trace · See it · Install · 60-second tour · Depth engraving · CLI · Presets · Help · Testing · Docs · Roadmap · License
| Job | Start here | |
|---|---|---|
| 🏷️ | Customer logo → mark file. Somebody emails a JPEG. Paste it, export a DXF at the exact millimetre width the part needs. | auto |
| 🔤 | Small text and serial plates. Counters (the holes in a, e, o, 8) survive and serifs stay sharp at 2 mm cap height. | small-text |
| ▦ | Codes that must scan. QR and Data Matrix modules stay square, separate and un-rounded. | qr-datamatrix |
| ✒️ | Line art and signatures. One stroke down the middle of each line instead of a hollow outline pair. | thin-line-art |
| ✂️ | Cut outside, engrave inside. Silhouette on CUT, detail on ENGRAVE, one file. |
cut-outer-engrave-inner |
| 🪙 | Depth (3D relief) engraving. A height map or a photo becomes a stack of cumulative passes with a real pass plan in mm and µm. | auto-depth |
| 🔁 | Repeatable shop jobs. Save what worked as customer-acme-tumbler, or drive the same pipeline headless over a folder. |
Save preset |
Those tools optimise for how a shape looks on screen. A laser cares about different things:
| Problem on the laser | LaserTrace Pro |
|---|---|
| 400-node "potato" circles, slow EZCAD import | Straight runs become lines, curves become a handful of Béziers. A circle is ~20 nodes at 50 mm; a rounded rectangle is 4 lines + 4 arcs. |
| Thin strokes traced as hollow outline pairs | Centerline engine: skeleton + junction-aware graph walk. One path per stroke, with the measured stroke width. Hybrid sends fills to outline and thin strokes to centerline automatically. |
| Overlapping shapes double-burn | Planar union of every same-layer fill. Zero overlap area is a quality gate. |
| Counters in A, B, O, 8 fill in | Holes come straight from the raster topology and are re-checked against the binary — the app warns if one was lost. |
| Speckle, JPEG blocks, grey halos become junk vectors | Non-destructive preprocess stack: despeckle in mm², halo knockout, bilateral, Sauvola with a global guard, deskew. |
| "Paths 50 %, Corners 60 %" | Controls in shop units: Minimum feature (mm), Despeckle (mm²), Darkness threshold, Detail vs cleanliness, Corner sharpness, Smoothness. |
| SVG in px that EZCAD mangles | DXF R2000/R12 in mm with $INSUNITS=4, Y-up, closed LWPOLYLINEs, layers ENGRAVE_FILL / ENGRAVE_LINE / CUT / SCORE. Also SVG, HPGL/PLT, PDF, 1-bit PNG. |
| No idea what will fail on the machine | Live stats and operator warnings: unclosed fills, holes lost, outline pairs suspected, tiny paths, node budget exceeded. |
| Grayscale "3D" that only changes colour | Real depth engraving: cumulative slices, wall draft, rotating hatch, Z steps and loop counts from a per-material removal table. |
Trace view — vectors over the source, with every node marked. The stats panel is the part that matters: 4 paths, 36 nodes, 3 holes kept, 99.4 % fidelity, complexity 1/100.
Depth view — the same window running a coin relief: 30 cumulative slices shaded light-to-dark, with the pass plan and material numbers on the right.
The machine next to the laser shouldn't need a development environment. Standalone builds are on the releases page:
| Download | For |
|---|---|
LaserTracePro-windows-x64.zip |
Windows 10/11 (64-bit) — unzip anywhere, run LaserTracePro.exe |
LaserTracePro-macos-arm64.zip |
macOS on Apple Silicon (M1 and later) |
What changed in each version is in CHANGELOG.md.
Intel Macs: there is no app build — GitHub's Intel macOS runner image is retired, and an Apple Silicon build cannot run on Intel (Rosetta only translates x86 → ARM, not the reverse). Install with pip instead; it is the same program.
These builds are unsigned, so the OS will warn you the first time. On Windows, SmartScreen says "Windows protected your PC" → More info → Run anyway. On macOS, right-click the app → Open → Open. Code-signing needs paid Apple and Microsoft certificates that this project doesn't have. If you'd rather not click through a warning, install from source below — it's the same program.
Needs Python 3.11+ and nothing else — no compiler, no system libraries. Works on Windows, macOS and Linux.
pip install "lasertrace[ui] @ git+https://github.com/JuicedSystems/lasertrace-pro.git"
lasertrace-ui # desktop app
lasertrace logo.png --width-mm 38 --out logo.dxf # or the CLIBoth commands land on your PATH. Drop the [ui] extra for the core only —
the tracer and CLI have no Qt dependency at all, which is what you want on a
server or in a batch job.
Prefer a virtual environment so this doesn't touch your system Python:
py -3.11 -m venv .venvthen.\.venv\Scripts\pip install ...on Windows, orpython3.11 -m venv .venvthen./.venv/bin/pip install ...elsewhere.
Windows (PowerShell)
git clone https://github.com/JuicedSystems/lasertrace-pro.git
cd lasertrace-pro
py -3.11 -m venv .venv
.\.venv\Scripts\pip install -r requirements-ui.txt # editable install + deps + pytest
.\.venv\Scripts\python -m lasertrace_ui.mainmacOS / Linux
git clone https://github.com/JuicedSystems/lasertrace-pro.git
cd lasertrace-pro
python3.11 -m venv .venv
./.venv/bin/pip install -r requirements-ui.txt # editable install + deps + pytest
./.venv/bin/python -m lasertrace_ui.mainThen run the tests — green straight from a clone, because the fixture set is committed:
pytest # 118 tests, ~2 minutesEvery push runs that suite on Linux, macOS and Windows × Python 3.11 and 3.12, then builds a wheel, installs it into a clean virtualenv and runs it from outside the source tree — because an editable install will happily hide a packaging bug that breaks everyone else. You can run that last check yourself:
cd /tmp && python /path/to/repo/tools/verify_install.pyUse requirements.txt instead for the headless core. Both files just install
the project's own extras, so pyproject.toml stays the
single source of truth for versions.
Ctrl+Vto paste, or drop a file (PNG, JPG, WEBP, BMP, TIF, GIF, PDF, SVG).- Leave the preset on AUTO — it measures the artwork and writes down every decision it made in the blue note ("classified as logo → logo-fill; already 1-bit → hard 50 % threshold; stroke width 3.67 mm → outline fill").
- Type the finished width in mm. Everything else is in real millimetres, so do this early.
- Press
2to check the binary and3to check the vectors. Most bad traces are bad binaries. - Read the warnings. Red is a problem the machine will show you; amber is one the customer will.
Eexports a DXF, or Copy SVG puts the vectors straight on the clipboard for LightBurn.
Space toggles the original · [ ] nudge the threshold · Enter re-traces ·
Ctrl+Z/Ctrl+Y walk the whole settings history · F1 opens the handbook.
Depth on a fiber laser comes from pass count, never from power. So a height map has to become a stack of passes — and they have to be cumulative: slice i contains everything deeper than i/N, not just the band between i/N and (i+1)/N. That nesting is what makes the deepest point receive every pass. Band slicing under-engraves deep areas, and it is the most common way people get this wrong. LightBurn's 3D Sliced mode and EZCAD3 are cumulative for the same reason.
LaserTrace Pro takes a grey height map — or a photo, run through gradient compression so luminance stops being mistaken for height — and produces:
<stem>_depth.dxf one layer + colour per slice (LightBurn keys on colour, EZCAD3 on name)
slices/<stem>_DEPTH_nn.dxf one file per slice, all sharing an IGNORE alignment frame (EZCAD2)
<stem>_heightmap.png 8/16-bit, black = deepest, DPI set from the hatch pitch
<stem>_preview.png shaded relief preview
<stem>_plan.md / .csv / .json pass plan: depths, Z offsets, loop counts, angles, time
…with wall draft on every slice, a hatch angle that rotates by 37° (never a divisor of 180, or the same lines repeat and cut grooves), and Z steps plus loop counts derived from a per-material removal table you can override with your own measured µm/pass.
Full write-up, including the measured removal figures and the exact LightBurn / EZCAD2 / EZCAD3 setup steps: docs/DEPTH_ENGRAVING.md.
lasertrace logo.png --preset logo-fill --width-mm 50 --out logo.dxf
lasertrace logo.png --out logo.dxf --out logo.svg --stats logo.json # auto-classify preset
lasertrace sketch.jpg --preset thin-line-art --out sketch.dxf # centerline
lasertrace tag.png --preset cut-outer-engrave-inner --out tag.dxf # CUT silhouette + ENGRAVE
lasertrace qr.png --preset qr-datamatrix --width-mm 20 --out qr.dxf # square modules, no smoothing
lasertrace --batch .\incoming --out-dir .\vectors --preset logo-fill --format dxf,svg
lasertrace --list-presets
lasertrace photo.jpg --classify
# depth: height map -> DEPTH_01..NN layers + the full pack
lasertrace relief.png --preset auto-depth --width-mm 40 --out relief.dxf --depth-pack .\relief_pack
lasertrace coin.png --preset depth-coin --depth-mm 0.3 --material brass --laser-w 60 --removal-um 12 --depth-pack .\coin
lasertrace face.jpg --preset depth-photo-relief --out face_heightmap.png # LightBurn 3D Sliced inputEvery UI control has a CLI flag (--detail,
--smoothness, --corner, --min-feature-mm, --despeckle-mm2,
--threshold, --node-budget, --engine, --mode, --dxf-version,
--curves, --origin). Same image + same preset = byte-identical
geometry, so batch jobs are repeatable and an export you shipped last year
can be reproduced — every file embeds the job settings that made it.
AUTO modes measure the image and derive the settings, then leave the
sliders editable and show their reasoning: auto (detect everything),
auto-bw (already black & white, or white on black), auto-photo (photos and
scans, tuned from measured noise), auto-lines (line art), auto-depth
(height maps and photo reliefs).
Static presets: logo-fill, thin-line-art, stamp-stencil,
photo-to-plate, small-text, qr-datamatrix, dirty-phone-photo,
cut-outer-engrave-inner, tiny-logo, depth-relief, depth-coin,
depth-photo-relief.
Each is a JSON file in
lasertrace/preset_data/ — copy one as a starting
point. Your own presets belong in ~/.lasertrace/presets/, which is
searched first and survives upgrades (the Save preset button writes there).
See docs/PRESETS.md.
Press F1 (or the ? Help button on the view bar) for a searchable, 29-topic handbook: what every control does, how depth engraving works, what each warning means and how to fix it, and step-by-step quick guides for the jobs a shop actually runs. Every panel has a small ? that opens its own topic.
The content is plain text in
lasertrace_ui/help_content.py — corrections
and new topics are easy PRs.
Quality here is measured, not eyeballed:
python tools/regress.pyTraces all 38 fixtures (35 flat + 3 height maps), writes reports/metrics.csv
and red/blue overlays in reports/overlays/, and fails if any preset
exceeds 3× its hand-set node target, loses a hole, leaves a fill open, drops
below 85 % fidelity, or produces overlapping fills. Depth fixtures are gated on
slice count, nesting (slice i+1 inside slice i) and closed paths instead.
The bar the tracer currently holds: a circle in 4 nodes, a rounded rectangle in 4 lines + 4 arcs, a ring in 8, a geometric logo in 36, and bold text in 59 with all nine counters intact.
| Document | What's in it |
|---|---|
| ARCHITECTURE.md | Modules, data flow, coordinate systems, file formats |
| LASER_REQUIREMENTS.md | EZCAD / LightBurn constraints, layer colours, DXF rules |
| TRACE_STRATEGY.md | Outline vs centerline vs hybrid, algorithm notes, roadmap |
| DEPTH_ENGRAVING.md | The physics, the research and its sources, the machine workflow |
| PRESETS.md | Every preset and its parameters |
| TECH_STACK.md | Stack and licence audit |
| EZCAD_VERIFY.md | How to verify an export in EZCAD |
| BUILDING.md | Building the standalone Windows / macOS apps |
The in-app help (F1) is the operator-facing summary of all of these.
Working today: paste/open → preprocess stack → contour, centerline, hybrid or Potrace-sidecar trace → hygiene → four views → DXF/SVG/PLT/PDF/PNG export, with AUTO modes, a headless CLI, batch mode, a 38-fixture regression suite, 118 tests, depth (3D relief) engraving end to end, and standalone Windows / macOS builds.
Next: geometry snap (recognising true circles, arcs and H/V/45° lines) and the vtracer engine. See the roadmap in docs/TRACE_STRATEGY.md.
Honest limits: the tracer is black-and-white only — no colour separation. Photo-to-plate output is a readable silhouette, not photoreal. Depth time estimates are only as good as your measured µm/pass, so calibrate first. EZCAD imports were verified against the format spec and reference files rather than on a live machine — bug reports from real controllers are very welcome.
Issues and pull requests are welcome — including "this file broke my EZCAD import", which is the most useful bug report this project can get. Start with CONTRIBUTING.md.
MIT — free to use, modify and sell, commercially or otherwise. See LICENSE.
Two deliberate constraints keep it that way:
sidecars/potrace_sidecar/is GPL-3, so Potrace is invoked as a separate process and never imported into the core. Everything works without it.- PyMuPDF (AGPL) is not used anywhere; PDF input goes through pypdfium2.
See NOTICE for third-party terms and docs/TECH_STACK.md for the full dependency licence audit.


