Automate the workflow of taking an image and spitting out STLs to use to put logos on 3D prints.
It can also be used for other workflows (vinyl cutting, laser engraving, etc.).
Split a logo/image into per-color PNG layers (with transparency), optionally re-run with a named palette, and export each layer to SVG and STL for manufacturing/printing.
- macOS GUI Application - Easy-to-use graphical interface
- Two-Stage Workflow - Preview layers, split if needed, then generate STL files
- Color Layer Splitting - Split a single color layer into multiple parts (top/bottom or left/right)
- Color Preview - Preview detected colors before processing
- Interactive Color Renaming - Visual color selector with rename dropdowns
- Auto (k-means) or Palette mode - Automatic color detection or manual palette
- Smart per-cluster ΔE thresholds + morphology cleanup
- White-aware gating + optional border-white removal
- Aligned outputs so multi-color STLs stack correctly
- PIL Fallback - Automatically handles ImageMagick crashes
- Per-layer Error Handling - Continues processing even if one layer fails
From the project root:
rm -rf dist/LogoToSTL.app
python3 -m PyInstaller gui/build_app.spec --clean -yThe built app will be in dist/LogoToSTL.app.
Note: Must run from project root, not from gui/ directory (spec file expects paths relative to root).
- Select Input File - Choose your logo image (PNG/JPG)
- Set Output Directory - Where STL files will be saved
- Configure Settings:
- Max Colors: Number of colors to detect (1-10)
- Min Area: Minimum pixel area for a color layer (smaller = more detail)
- STL Height: Extrusion height in mm
- STL Scale: XY scale factor
- Preview Layers - Click to generate color-separated layers
- Review & Split Layers (optional):
- Review the generated color layers
- Click "Split" on any layer to divide it into two parts
- Choose "Split Top/Bottom" or "Split Left/Right"
- Split layers will be numbered (e.g.,
blue1.png,blue2.png)
- Generate STL Files - Process all layers (including split ones) into STL files
- Two-Stage Processing: Preview layers first, then generate STL files
- Color Layer Splitting: Split any color layer into multiple parts for separate STL generation
- Color Preview: Preview detected colors with visual swatches
- Color Selector: Interactive table to rename detected colors
- Progress Updates: Real-time status messages during processing
- Error Display: Detailed error messages if something goes wrong
- Fine Details: Lower "Min Area" (e.g., 500-1000) to preserve small details like tails, thin lines, or small features. The default 1000 may filter out fine details.
- Color Accuracy: Use the color preview and rename feature to fix incorrect color names before generating STL files.
- Multiple Attempts: If details are missing, try:
- Lowering "Min Area" to 500 or even 100
- Checking the generated PNG layers to see if detail is lost during color separation or vectorization
- The vectorization process (Potrace) may simplify complex shapes - this is normal for SVG conversion
The core functionality is also available via command line:
Python
opencv-pythonnumpy
pip install opencv-python numpyCLI tools
- ImageMagick (
convert) — for PNG→PBM - Potrace — PBM→SVG
- OpenSCAD — SVG→STL
# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y imagemagick potrace openscadpython color_layers.py INPUT_IMAGE.[png|jpg] \
--mode auto --k 5 --bilateral \
--auto-finalize \
--rename "aqua:white,green:blue,teal:lightgray" \
--min-area 10000 \
--vectorize \
--stl --stl-height 2.5 --stl-scale 1.0 \
--outdir layers_finalWhat that does:
- Auto mode clusters colors (k=5), smooths JPEG artifacts (
--bilateral). - Writes discovered palette to
OUTDIR/<base>-palette.txt. - Auto-finalize: re-runs in palette mode using that palette.
- Applies rename map so filenames become friendly (e.g.,
blue,white,lightgray). - Drops tiny specks (
--min-area 10000). - Vectorizes each PNG layer to SVG (
svgs/). - Extrudes each SVG to STL (
stl/) at 2.5 mm height.
Outputs inside OUTDIR:
basename-<color>.png— one per color layer (transparent background)basename-contact.png— labeled contact sheet of layerssvgs/basename-<color>.svg— vector per layerstl/basename-<color>.stl— extruded STL per layerbasename-palette.txt— discovered palette (hex:name list)
python color_layers.py input.png --mode auto --k 4 --outdir layerspython color_layers.py input.png \
--mode palette \
--palette "#489fc7:blue,#1b1c1d:black,#585b5c:darkgray,#bbbebf:lightgray,#f3f5f5:white" \
--outdir layers_namedpython color_layers.py test-logo.png \
--mode auto --k 5 --bilateral \
--auto-finalize \
--rename "aqua:white,green:blue,teal:lightgray" \
--min-area 10000 \
--vectorize \
--stl --stl-height 2.5 --stl-scale 1.0 \
--outdir layers_final--mode auto/--k K– find K color clusters automatically.--mode palette/--palette "#rrggbb:name,..."– use your palette; names become filenames.--bilateral– edge-preserving denoise (great for JPEG logos).
--delta N– fixed LAB tolerance; omit to use adaptive per-cluster ΔE.--open,--close– base morphology kernel sizes (smart mode adapts per layer).--min-area N– drop tiny residue masks (< N pixels).
- Smart white gating is built-in; it keeps interior whites and can drop big border-touching white backgrounds.
--keep-bg-white– keep border whites (off by default).--no-ignore-white– process near-white pixels too.- Extra tunables:
--white-l-min,--white-chroma-max,--white-thresh.
--vectorize– create SVGs inOUTDIR/svgs.--stl– extrude each SVG to STL inOUTDIR/stl.--stl-height– extrusion height in mm (e.g.,2.5).--stl-scale– uniform XY scaling.--stl-center– leave this OFF to keep all layers aligned to the same origin.
--auto-finalize– after auto clustering, immediately re-run in palette mode using the discovered palette.--rename "src:dst,src2:dst2"– rename auto names (case-insensitive).
-
App crashes on "Back to Preview"
Fixed in latest version. If it still occurs, try selecting the file again. -
Missing details in generated STL
Lower the "Min Area" setting (try 500-1000) to preserve fine details like thin lines, tails, or small features. -
Color names don't match actual colors
Use the color preview and color selector to rename colors before generating STL files. -
ImageMagick crashes
The app automatically uses PIL fallback. This is normal and handled transparently. -
Fewer STL files than expected
Check the warning dialog - some layers may be skipped if they're too small (below min_area threshold).
-
"convert: command not found"
Install ImageMagick:brew install imagemagick(macOS) orsudo apt-get install -y imagemagick(Linux) -
Potrace missing
brew install potrace(macOS) orsudo apt-get install -y potrace(Linux) -
OpenSCAD errors / STL not produced
Ensure OpenSCAD is installed and on PATH:brew install --cask openscad(macOS) -
Layers don't stack in CAD
Make sure you didn't pass--stl-center. -
Fewer SVG/STL files than PNG layers
Some layers may be skipped if under--min-area.
- Uses OpenCV, ImageMagick, Potrace, and OpenSCAD.
- Be mindful of logo/IP licensing when using outputs.