A powerful Node.js library for converting PNG images to SVG using Potrace and Jimp. This tool performs bitmap tracing to create scalable vector graphics from raster images.
- Convert PNG images to SVG format using advanced tracing algorithms
- Multiple conversion presets for different image types (logo, photo, drawing, text)
- Posterization support for multi-level SVG output
- Command-line interface for batch processing
- TypeScript support with full type definitions
- Customizable tracing parameters for fine-tuned results
npm installThis converter uses a two-step process:
-
Jimp: Preprocesses the PNG image
- Converts to grayscale
- Applies contrast and normalization
- Performs threshold-based binarization
-
Potrace: Traces the bitmap to create vector paths
- Converts bitmap to mathematical curves
- Optimizes paths for smoother output
- Generates clean SVG markup
import { PngToSvgConverter } from './src/converter.js';
const converter = new PngToSvgConverter();
// Basic conversion
await converter.convertFile('input.png', 'output.svg');
// With custom options
const options = {
threshold: 128, // Black/white cutoff (0-255)
turdSize: 2, // Remove noise up to this size
optCurve: true, // Enable curve optimization
turnPolicy: 'minority', // Path direction preference
};
await converter.convertFile('input.png', 'output.svg', options);
// Using presets
const logoOptions = PngToSvgConverter.getPresetOptions('logo');
await converter.convertFile('logo.png', 'logo.svg', logoOptions);
// Convert from buffer (useful for web applications)
const pngBuffer = fs.readFileSync('input.png');
const svgString = await converter.convertBuffer(pngBuffer, options);
// Posterized SVG (multi-color levels)
await converter.convertToPosterized('input.png', 'output.svg', 4);# Build the project first
npm run build
# Basic conversion
node dist/cli.js convert input.png output.svg
# With options
node dist/cli.js convert input.png output.svg --threshold 140 --preset logo
# Posterized conversion
node dist/cli.js posterize input.png output.svg --steps 6
# Batch processing
node dist/cli.js batch ./input-folder ./output-folder --preset drawing| Option | Type | Default | Description |
|---|---|---|---|
threshold |
number | 128 | Black/white threshold (0-255). Lower = more black areas |
turdSize |
number | 2 | Remove noise/speckles up to this size |
alphaMax |
number | 1 | Corner threshold for smoothness |
optCurve |
boolean | true | Enable curve optimization |
optTolerance |
number | 0.2 | Curve optimization tolerance |
turnPolicy |
string | 'minority' | Path direction: 'minority', 'majority', 'black', 'white', 'left', 'right' |
blackOnWhite |
boolean | true | Color interpretation |
The library includes optimized presets for different image types:
threshold: 128turdSize: 2optCurve: trueoptTolerance: 0.2- Best for: Simple graphics, logos, icons
threshold: 120turdSize: 4optTolerance: 0.3- Best for: Complex photographic images
threshold: 140turdSize: 1optTolerance: 0.1- Best for: Hand-drawn illustrations, sketches
threshold: 128turdSize: 1optCurve: false- Best for: Text-heavy images, documents
-
Run Examples:
npm run examples
-
Try CLI:
npm run cli convert examples/sample.png examples/output.svg --preset logo
-
Development:
npm run dev # Watch mode
src/
βββ converter.ts # Main conversion logic
βββ cli.ts # Command-line interface
βββ examples.ts # Usage examples and demos
βββ index.ts # Main entry point
# Install dependencies
npm install
# Build TypeScript
npm run build
# Watch mode (development)
npm run dev
# Run examples
npm run examplesapp.post('/convert', async (req, res) => {
const pngBuffer = req.file.buffer;
const svgString = await converter.convertBuffer(pngBuffer);
res.type('image/svg+xml').send(svgString);
});const files = await fs.readdir('./images');
const pngFiles = files.filter((f) => f.endsWith('.png'));
for (const file of pngFiles) {
const output = file.replace('.png', '.svg');
await converter.convertFile(`./images/${file}`, `./svg/${output}`);
}const customOptions = {
threshold: 140, // More white areas
turdSize: 3, // Remove small noise
optCurve: true, // Smooth curves
optTolerance: 0.1, // High precision
turnPolicy: 'minority',
};- Logos: Use 'logo' preset with high contrast source images
- Photos: Use 'photo' preset and experiment with threshold values
- Text: Use 'text' preset with clean, high-resolution source
- Noise: Increase
turdSizeto remove unwanted small elements - Smoothness: Adjust
optTolerancefor curve smoothness vs. accuracy
- Low quality output: Try adjusting
thresholdvalue - Too much noise: Increase
turdSizeparameter - Blocky curves: Enable
optCurveand adjustoptTolerance - Missing details: Lower
turdSizeandthreshold
- Jimp: Image processing and manipulation
- Potrace: Bitmap tracing to vector graphics
- Commander: Command-line interface
ISC
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Happy converting! π