One-click SVG / image → Bambu Lab AMS print files converter, self-hosted in Docker.
Drop an SVG (or PNG/JPG/GIF/BMP/WebP/TIFF) on the build plate, get back a zip of per-color watertight STLs plus parametric OpenSCAD source, ready to drag into Bambu Studio and assign to AMS filament slots.
- Automatic color reduction to up to 4 AMS slots — adaptive: a 2-color logo stays 2 colors, a busy image uses all 4. Slot colors are editable before conversion (renames STLs and recolors the SCAD).
- Raster support — pure-Python vectorization (median pre-filter, adaptive k-means, marching-squares tracing). Anti-aliased edges and JPEG artifacts get absorbed into the real palette; transparent pixels are excluded from the model.
- Geometry cleanup & polygon repair — even-odd fill resolution,
make_valid, degenerate-ring removal. - Hole detection — interior rings (letter counters, cutouts) preserved through to the meshes and reported.
- Minimum feature width filtering — morphological opening removes details narrower than your nozzle can print (default 0.4 mm, configurable, 0 disables).
- Automatic STL naming —
name_2_ff0000.stl(slot number + hex) so filament assignment in Bambu Studio is obvious. - OpenSCAD generation — a
.scadwithbase_thickness/color_thicknessparameters ships in every zip for re-rendering with different numbers. - Optional 150 mm scaling — longest side scaled to 150 mm (on by default), or native document size.
- Thickness arguments — base plate (default 2 mm) + raised color layers (default 0.8 mm).
All STLs are verified-watertight: extrusion falls back from earcut to Shewchuk's
triangle engine for polygons with many holes.
docker build -t svg2bambu .
docker run -d --name svg2bambu --restart unless-stopped -p 5002:5000 svg2bambuOpen http://<host>:5002, drop a file, click Convert, download the zip.
- Drag all
.stlfiles from the zip into Bambu Studio at once. - Answer Yes to "Load these files as a single object with multiple parts?"
- Parts arrive pre-aligned: base at Z0, color layers raised on top.
- Select each part and assign the AMS filament matching the hex in its filename.
- Slice and print.
| Endpoint | Method | Purpose |
|---|---|---|
/api/analyze |
POST (multipart svg) |
detect palette, returns job_id |
/api/convert/<job_id> |
POST (JSON options) | start conversion |
/api/status/<job_id> |
GET | progress log + stats |
/api/download/<job_id> |
GET | the zip |
Convert options: scale_150 (bool), base_mm, color_mm, min_feature_mm,
overrides ({"#detected": "#replacement"}).
Flask + gunicorn · svgelements · shapely · trimesh · scikit-image · pillow · numpy · mapbox-earcut · triangle