Please bookmark this page to avoid losing your image tool!

Image To Vector Converter

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, turdsize = 2, opttolerance = 0.2, alphamax = 1, turnpolicy = 'minority', threshold = -1, invertColors = 0) {

    // Define loader as a static property of the function to encapsulate it
    // This ensures the script is loaded only once across multiple calls to processImage.
    if (typeof processImage.potraceLoader === 'undefined') {
        processImage.potraceLoader = {
            promise: null,
            load: function() {
                if (this.promise) {
                    return this.promise;
                }
                this.promise = new Promise((resolve, reject) => {
                    // Check if Potrace is already available (e.g., loaded by another instance of this function)
                    if (typeof Potrace !== 'undefined') {
                        resolve();
                        return;
                    }
                    const script = document.createElement('script');
                    script.src = 'https://unpkg.com/potrace@2.1.8/potrace.js'; // CDN link for Potrace library
                    script.onload = () => {
                        // Potrace class should now be available on the window object
                        if (typeof Potrace !== 'undefined') {
                            resolve();
                        } else {
                            this.promise = null; // Reset promise on failure
                            reject(new Error('Potrace script loaded but Potrace class not found.'));
                        }
                    };
                    script.onerror = (err) => {
                        this.promise = null; // Reset promise on failure
                        console.error("Failed to load Potrace.js from CDN.", err);
                        reject(new Error('Failed to load Potrace.js from CDN. Check network or CDN link.'));
                    };
                    document.head.appendChild(script);
                });
                return this.promise;
            }
        };
    }

    // 1. Validate the input image
    // Check if originalImg is a loaded HTMLImageElement
    if (!originalImg || !(originalImg instanceof HTMLImageElement) || !originalImg.complete || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
        console.error("Image is not fully loaded, is invalid, or has zero dimensions.");
        const errorDiv = document.createElement('div');
        errorDiv.textContent = "Error: Input image is not usable. Please ensure it's a fully loaded image with valid dimensions.";
        return errorDiv;
    }

    // 2. Load the Potrace library
    try {
        await processImage.potraceLoader.load();
    } catch (error) {
        const errorDiv = document.createElement('div');
        errorDiv.textContent = error.message || "Error: Could not load the Potrace vectorization library.";
        return errorDiv;
    }

    // 3. Prepare Potrace parameters
    let potraceTurnPolicyValue;
    // Potrace.TURNPOLICY_* are constants defined by the Potrace library
    switch (String(turnpolicy).toLowerCase()) {
        case 'black': potraceTurnPolicyValue = Potrace.TURNPOLICY_BLACK; break;
        case 'white': potraceTurnPolicyValue = Potrace.TURNPOLICY_WHITE; break;
        case 'left': potraceTurnPolicyValue = Potrace.TURNPOLICY_LEFT; break;
        case 'right': potraceTurnPolicyValue = Potrace.TURNPOLICY_RIGHT; break;
        case 'minority': potraceTurnPolicyValue = Potrace.TURNPOLICY_MINORITY; break;
        case 'majority': potraceTurnPolicyValue = Potrace.TURNPOLICY_MAJORITY; break;
        default:
            console.warn(`Invalid turnpolicy "${turnpolicy}", using default 'minority'.`);
            potraceTurnPolicyValue = Potrace.TURNPOLICY_MINORITY;
    }

    const potraceParams = {
        turdSize: Number(turdsize),         // Suppress speckles of this size (pixels)
        alphaMax: Number(alphamax),         // Corner threshold parameter
        optTolerance: Number(opttolerance), // Curve optimization tolerance
        turnPolicy: potraceTurnPolicyValue, // How to resolve ambiguities in path decomposition
        threshold: Number(threshold),       // Threshold level (0-255). Use -1 (Potrace.THRESHOLD_AUTO) for auto.
        invert: (Number(invertColors) === 1) // Invert the input image (black on white vs. white on black)
    };

    // 4. Perform vectorization using Potrace
    try {
        const P = new Potrace(); // Instantiate Potrace
        P.setParameters(potraceParams);  // Set tracing parameters
        P.loadImageFromImg(originalImg); // Load image data from the HTMLImageElement
        P.process();                     // Perform the tracing operation (synchronous)

        const svgString = P.getSVG();    // Get the result as an SVG string

        // 5. Validate and parse SVG string
        if (!svgString || svgString.trim() === "") {
            console.warn("Potrace.getSVG() returned an empty string. This might be due to image content or parameters.");
            const messageDiv = document.createElement('div');
            messageDiv.textContent = "Vectorization resulted in an empty output. Try adjusting parameters (e.g., threshold, invertColors) or check the image content.";
            return messageDiv;
        }

        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = svgString; // Parse SVG string into DOM
        const svgElement = tempDiv.firstChild;

        if (!svgElement || typeof svgElement.tagName !== 'string' || svgElement.tagName.toLowerCase() !== 'svg') {
            console.error("Failed to parse SVG string into an SVG element from Potrace output.");
            const errorDiv = document.createElement('div');
            errorDiv.textContent = "Error: Could not create SVG element from vectorization output.";
            return errorDiv;
        }

        // 6. Check if the SVG contains any actual vector paths for better user feedback
        if (!svgElement.querySelector('path')) {
            // Potrace produces an SVG wrapper (e.g., <svg width="..." height="..."></svg>) even if no paths are found.
            console.warn("Vectorization did not find any paths in the image.");
            const messageDiv = document.createElement('div');
            messageDiv.textContent = "Vectorization did not find any paths. The image might be blank after thresholding, or too simple. Try different parameters.";
            // Optionally, one might still return the empty SVG structure:
            // svgElement.setAttribute('width', '100%');
            // svgElement.setAttribute('height', '100%');
            // return svgElement;
            return messageDiv;
        }
        
        // 7. Prepare SVG for display
        // Potrace SVG usually includes width/height in pixels and a viewBox.
        // Setting width/height to 100% makes it scale within its container.
        svgElement.setAttribute('width', '100%');
        svgElement.setAttribute('height', '100%');
        // The viewBox attribute (set by Potrace) will ensure correct aspect ratio.

        return svgElement;

    } catch (err) {
        console.error("Error during Potrace processing or SVG handling:", err);
        const errorDiv = document.createElement('div');
        // Sanitize error message if needed, but for local display it's fine.
        errorDiv.textContent = `Error during vectorization: ${err.message || 'An unknown error occurred.'}`;
        return errorDiv;
    }
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image To Vector Converter allows users to convert raster images into vector graphics format (SVG). This tool is particularly useful for graphic designers, illustrators, and anyone looking to create scalable images from pixel-based graphics. It supports customization options such as adjusting the level of detail, optimizing paths, and inverting colors to achieve the desired output. Users can use this converter for tasks such as logo creation, graphic design, and preparing images for printing, where vector graphics are advantageous due to their scalability without loss of quality.

Leave a Reply

Your email address will not be published. Required fields are marked *