Low-Res Logo Rescue
What this does and why
Clients constantly send logos that are too small and soft for large-format print, then re-send the same file when asked for something better, because they don't have anything better. This skill does two jobs: it honestly diagnoses what the file actually is, and it runs a Python cleanup pipeline that maximizes readability and produces the best possible input for vectorizing.
The key insight: for a flat logo (solid colors, text, hard shapes), the winning move is not neural upscaling. It's denoise, then a clean Lanczos upscale, then sharpen, then flatten the fuzzy anti-aliased pixels back to a small set of solid colors. That last step is what makes edges snap crisp, and a flat-color raster is exactly what an auto-tracer wants. For a photograph or scan of a physical object, no tool can manufacture edge detail that was never captured, so the script says so and you stop wasting time trying to trace it.
Workflow
Follow these steps in order. Steps 1 and 4 are judgment; step 2 is the script.
Step 1: Diagnose the file first
Before processing, look at the image and classify it, because it determines whether a faithful vector is even possible:
- Flat art (vectorizable): logos, wordmarks, icons, badges with solid fills and hard edges. These clean up well and trace into faithful vectors.
- Photographic / physical object (NOT vectorizable into a faithful vector): a photo or scan of a medallion, coin, embroidered patch, painted sign, or 3D object. Tell-tale signs are soft dimensional shading, lighting gradients, and tens of thousands of unique colors. Upscaling helps legibility a little; tracing produces a mush of thousands of anchor points. Do not promise a "true to original" vector from these.
The script also prints a flatness estimate and labels each file flat art or photographic so you can confirm your read.
A filename like ..._cloud-recover_2x or ..._gigapixel means someone already ran a neural upscaler. If it's still soft after that, that confirms the detail isn't recoverable, so don't expect this pipeline to do better on sharpness; its value there is the flatten/readability pass.
Step 2: Run the enhancement script
The bundled script has no exotic dependencies. Ensure they're present, then run it:
pip install --break-system-packages numpy opencv-contrib-python scikit-learn pillow
python3 scripts/enhance_logo.py "PATH/TO/logo.png" --outdir "PATH/TO/output"It accepts multiple files, globs, or a folder, and writes three variants per image:
<stem>_A_enhanced.png: natural denoise + upscale + sharpen + gentle contrast. No posterization. The safe general-purpose upscale; good when you just need a bigger, cleaner raster.<stem>_B_flat<N>.png: the enhanced image flattened to N solid colors. This is usually the most readable version and the one to hand a vector tracer. N is auto-chosen from the art's complexity; override with--colorsif the palette looks wrong (too few merges distinct colors, too many keeps noise).<stem>_C_traceready.png: flattened, high-contrast, composited on solid white. A dedicated bitmap-trace source.
Useful flags: --scale (max upscale factor, default 3), --long-edge (cap the upscaled long edge in pixels, default 3600), --colors (force the flatten palette size).
Step 3: Review the variants before handing anything off
Open the outputs and check them at full size. Confirm the flatten didn't merge two brand colors into one or leave a jagged halo. Watch for artifacts that were baked into the source, e.g. a soft drop shadow behind text often survives the flatten as an ugly gray band; note it so it gets dropped during vectorizing. If the palette is off, rerun with --colors.
Step 4: Route to the right vectorization path
Cleaning the raster is rarely the end goal. Pick the path that gets a real, faithful vector:
- Find the real/official vector first. This beats any pixel work. Pull the logo from the client's website (inline SVG or largest PNG), their brand/press kit, a vendor or member portal, or, for a known brand or organization, an official brand-asset page or a vector logo site. Re-ask the client for the specific thing using file extensions they can act on: "the original vector logo (.ai, .eps, .svg, or a vector .pdf) from whoever designed it." Vague requests for "a better file" are why they keep re-sending the same JPG.
- Rebuild it (best for text-heavy or brandable logos). Most bad logo files are wordmarks. Identify the font (WhatTheFont, Illustrator's Retype, Font Squirrel Matcherator), set the type live, and recreate the marks. Sharper and more faithful than tracing. For known-brand marks, pull the official vector components and match the brand-guide colors rather than eyeballing.
- Trace the flat file (fallback). Feed
_B_flator_C_tracereadyto Illustrator Image Trace, Vector Magic (best auto-tracer), or Inkscape/potrace (free). Expect ~10 minutes of manual node cleanup after. Only do this for flat art.
Do not regenerate the logo with an AI image model when fidelity matters. It produces plausible-but-wrong results, the opposite of "true to original."
Honest expectations
- Flat art: expect a clearly crisper, larger, trace-ready result. Real win.
- Photographic/physical-object source: expect a modest legibility bump and nothing trace-worthy. The honest answer to the client is to retrieve the original vector or rebuild it.
- If the logo is trademarked (an ® or ™ is visible), rebuilding a client's own mark for their own materials is routine, but work from official assets and brand-guide colors rather than approximating.
Notes
- The pipeline is deterministic and offline; nothing is uploaded and no models are downloaded.
opencv-contrib-pythonandopencv-pythoncan conflict; if imports break, uninstall one and keepopencv-contrib-python.