Please bookmark this page to avoid losing your image tool!

Photo 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.
/**
 * Converts a raster image (photo) into a vector-like stylized image.
 * This is achieved by reducing the number of colors (posterization) and adding outlines.
 *
 * @param {HTMLImageElement} originalImg The original image element to process.
 * @param {number | string} colors The target number of colors in the final image. The actual number will be a cube of an integer close to the cube root of this value (e.g., 8 becomes 2^3=8, 10 becomes 2^3=8, 27 becomes 3^3=27). Default is 8.
 * @param {number | string} blurRadius The radius of the blur filter applied before processing. A larger value simplifies shapes and reduces noise, leading to smoother color areas. Set to 0 to disable. Default is 1.
 * @param {number | string} outlineThreshold The sensitivity for edge detection. A higher value means only more significant color differences will create an outline. Set to 0 to disable outlines. The value represents the sum of differences in R, G, B channels (0-765). Default is 40.
 * @returns {HTMLCanvasElement} A new canvas element with the vector-like image.
 */
function processImage(originalImg, colors = 8, blurRadius = 1, outlineThreshold = 40) {
    // Coerce parameters to numbers to ensure they are of the correct type.
    const numColors = Number(colors) || 8;
    const numBlurRadius = Number(blurRadius) || 0;
    const numOutlineThreshold = Number(outlineThreshold) || 0;

    // 1. Setup Canvas and context.
    // Using { willReadFrequently: true } can optimize performance for repeated getImageData calls.
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    // 2. Pre-processing: Apply a blur to simplify details and reduce noise.
    // This helps in creating larger, more uniform color areas, typical of vector graphics.
    if (numBlurRadius > 0) {
        ctx.filter = `blur(${numBlurRadius}px)`;
    }
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    // Reset the filter so it doesn't affect subsequent drawing operations like putImageData.
    ctx.filter = 'none';

    // 3. Get pixel data from the (potentially blurred) original image.
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    // 4. Color Quantization (Posterization).
    // This step reduces the image to a limited color palette.
    // We approximate the desired number of colors by finding the number of levels per RGB channel.
    const levelsPerChannel = Math.max(2, Math.round(Math.cbrt(numColors)));
    const step = 255 / (levelsPerChannel - 1);

    // Create a new array to hold the pixel data after posterization.
    const posterizedData = new Uint8ClampedArray(data.length);
    for (let i = 0; i < data.length; i += 4) {
        posterizedData[i] = Math.round(data[i] / step) * step; // Red
        posterizedData[i + 1] = Math.round(data[i + 1] / step) * step; // Green
        posterizedData[i + 2] = Math.round(data[i + 2] / step) * step; // Blue
        posterizedData[i + 3] = data[i + 3]; // Alpha
    }

    // 5. Edge Detection for Outlines.
    // If an outline is desired, this pass detects sharp color changes in the posterized image
    // and draws black pixels, simulating vector outlines.
    if (numOutlineThreshold > 0) {
        const finalData = new Uint8ClampedArray(data.length);
        const w = canvas.width;
        const h = canvas.height;

        for (let y = 0; y < h; y++) {
            for (let x = 0; x < w; x++) {
                const i = (y * w + x) * 4;
                let isEdge = false;

                const r1 = posterizedData[i];
                const g1 = posterizedData[i + 1];
                const b1 = posterizedData[i + 2];

                // Check right neighbor for a color difference.
                if (x < w - 1) {
                    const iRight = i + 4;
                    const diff = Math.abs(r1 - posterizedData[iRight]) +
                        Math.abs(g1 - posterizedData[iRight + 1]) +
                        Math.abs(b1 - posterizedData[iRight + 2]);
                    if (diff > numOutlineThreshold) {
                        isEdge = true;
                    }
                }

                // Check bottom neighbor for a color difference.
                if (y < h - 1 && !isEdge) {
                    const iBottom = i + (w * 4);
                    const diff = Math.abs(r1 - posterizedData[iBottom]) +
                        Math.abs(g1 - posterizedData[iBottom + 1]) +
                        Math.abs(b1 - posterizedData[iBottom + 2]);
                    if (diff > numOutlineThreshold) {
                        isEdge = true;
                    }
                }

                if (isEdge) {
                    finalData[i] = 0; // Black
                    finalData[i + 1] = 0;
                    finalData[i + 2] = 0;
                    finalData[i + 3] = posterizedData[i + 3]; // Preserve alpha
                } else {
                    finalData[i] = r1;
                    finalData[i + 1] = g1;
                    finalData[i + 2] = b1;
                    finalData[i + 3] = posterizedData[i + 3];
                }
            }
        }
        // Place the new pixel data with outlines onto the canvas.
        imageData.data.set(finalData);
    } else {
        // If no outlines, just use the posterized data.
        imageData.data.set(posterizedData);
    }

    ctx.putImageData(imageData, 0, 0);

    // 6. Return the final canvas element.
    return canvas;
}

Free Image Tool Creator

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

Description

The Photo To Vector Converter transforms raster images (such as photographs) into a stylized, vector-like appearance. By reducing the number of colors in the image and applying outlines, this tool allows users to create simplified graphics that resemble vector art. It can be particularly useful for designers looking to create logos, icons, or graphics for digital media, as well as for artists looking to reinterpret photos in a stylized manner.

Leave a Reply

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