Please bookmark this page to avoid losing your image tool!

Image Cartoonizer

(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 an image to a cartoon-like appearance by reducing the color palette (posterization)
 * and outlining the edges in black.
 *
 * @param {HTMLImageElement} originalImg The source image object to be processed.
 * @param {number} colorLevels The number of distinct color levels per channel for the posterization effect. A lower number (e.g., 4-8) creates a more stylized, flat look. Must be 2 or greater.
 * @param {number} edgeThreshold A value from 0 to 255 that determines the sensitivity of edge detection. Higher values result in fewer, thicker outlines around more prominent edges.
 * @returns {HTMLCanvasElement} A new canvas element displaying the cartoonized image.
 */
function processImage(originalImg, colorLevels = 8, edgeThreshold = 35) {
    // Create a canvas element and get its 2D context
    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } is a performance hint for the browser
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });

    // Set canvas dimensions to match the intrinsic size of the image
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0);

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

    // Create a read-only copy of the original pixel data to avoid processing already modified pixels
    const sourceData = new Uint8ClampedArray(data);

    // Ensure colorLevels is a usable integer (at least 2 for division to work)
    const levels = Math.max(2, Math.floor(colorLevels));
    // Calculate the step size for color quantization
    const step = 255 / (levels - 1);

    // Helper function to calculate the grayscale (luminance) of a color
    const getGrayscale = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;

    // Helper to get the posterized grayscale value from the source data at a specific pixel index
    const getPosterizedGray = (source, index, stepValue) => {
        const r = source[index];
        const g = source[index + 1];
        const b = source[index + 2];

        // Apply posterization to each channel
        const pr = Math.round(r / stepValue) * stepValue;
        const pg = Math.round(g / stepValue) * stepValue;
        const pb = Math.round(b / stepValue) * stepValue;

        return getGrayscale(pr, pg, pb);
    };

    // Iterate over each pixel of the image
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const i = (y * width + x) * 4;

            // --- 1. Get the posterized color for the current pixel ---
            const r = sourceData[i];
            const g = sourceData[i + 1];
            const b = sourceData[i + 2];

            const pr = Math.round(r / step) * step;
            const pg = Math.round(g / step) * step;
            const pb = Math.round(b / step) * step;

            // --- 2. Detect edges by comparing with neighboring pixels ---
            let isEdge = false;

            // Skip border pixels to avoid out-of-bounds array access
            if (x > 0 && x < width - 1 && y > 0 && y < height - 1) {
                const currentGray = getGrayscale(pr, pg, pb);

                // Get posterized gray values of neighbors to the right and bottom
                const rightGray = getPosterizedGray(sourceData, (y * width + (x + 1)) * 4, step);
                const bottomGray = getPosterizedGray(sourceData, ((y + 1) * width + x) * 4, step);

                // If the difference in brightness is greater than the threshold, it's an edge
                if (Math.abs(currentGray - rightGray) >= edgeThreshold || Math.abs(currentGray - bottomGray) >= edgeThreshold) {
                    isEdge = true;
                }
            }

            // --- 3. Write the final pixel color to the output data ---
            if (isEdge) {
                // Set edge pixels to black
                data[i] = 0;
                data[i + 1] = 0;
                data[i + 2] = 0;
            } else {
                // Set non-edge pixels to their posterized color
                data[i] = pr;
                data[i + 1] = pg;
                data[i + 2] = pb;
            }
            // Preserve the original alpha channel
            data[i + 3] = sourceData[i + 3];
        }
    }

    // Put the modified pixel data back onto the canvas
    ctx.putImageData(imageData, 0, 0);

    // 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 Image Cartoonizer tool transforms standard images into cartoon-style visuals by applying a posterization effect that reduces the color palette and outlines edges in black. This tool is ideal for artists looking to create stylized artwork, for social media users wanting to add flair to their photos, or for any project that requires a fun and artistic representation of an image. Users can customize the number of colors in the output and the edge detection sensitivity to achieve a unique cartoon effect.

Leave a Reply

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