Please bookmark this page to avoid losing your image tool!

Image Cartoonizer From Photo

(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 photo into a cartoon-style image by applying color posterization and edge detection.
 *
 * @param {Image} originalImg The original Image object to be processed.
 * @param {number} colorLevels The number of color levels for posterization. Fewer levels result in a more stylized, flatter look.
 * @param {number} blurRadius The radius of the Gaussian blur applied before posterization to smooth color areas.
 * @param {number} edgeThreshold The sensitivity for edge detection. A lower value detects more lines.
 * @param {string} edgeColor A comma-separated RGB string (e.g., '0,0,0') for the color of the detected edges.
 * @returns {HTMLCanvasElement} A canvas element with the cartoonized image.
 */
function processImage(originalImg, colorLevels = 8, blurRadius = 5, edgeThreshold = 80, edgeColor = '0,0,0') {
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;

    // Create the final canvas that will be returned.
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Parse the edge color string into R, G, B components.
    const [r, g, b] = edgeColor.split(',').map(c => parseInt(c.trim(), 10));

    // --- Step 1: Create the color-posterized base layer ---
    const colorCanvas = document.createElement('canvas');
    colorCanvas.width = width;
    colorCanvas.height = height;
    const colorCtx = colorCanvas.getContext('2d', {
        willReadFrequently: true
    });

    // Apply a blur to smooth out details and help colors clump together.
    if (blurRadius > 0) {
        colorCtx.filter = `blur(${blurRadius}px)`;
    }
    colorCtx.drawImage(originalImg, 0, 0, width, height);

    // Get pixel data from the blurred image.
    const imageData = colorCtx.getImageData(0, 0, width, height);
    const data = imageData.data;

    // Apply posterization to reduce the number of colors.
    const levels = Math.max(2, Math.min(255, colorLevels));
    const factor = 255 / (levels - 1);

    for (let i = 0; i < data.length; i += 4) {
        data[i] = Math.round(data[i] / factor) * factor; // Red
        data[i + 1] = Math.round(data[i + 1] / factor) * factor; // Green
        data[i + 2] = Math.round(data[i + 2] / factor) * factor; // Blue
    }
    colorCtx.putImageData(imageData, 0, 0);


    // --- Step 2: Create the edge detection layer ---
    const edgeCanvas = document.createElement('canvas');
    edgeCanvas.width = width;
    edgeCanvas.height = height;
    const edgeCtx = edgeCanvas.getContext('2d', {
        willReadFrequently: true
    });

    // Draw the original image and convert it to grayscale for edge detection.
    edgeCtx.filter = 'grayscale(100%)';
    edgeCtx.drawImage(originalImg, 0, 0, width, height);

    const grayImageData = edgeCtx.getImageData(0, 0, width, height);
    const grayData = grayImageData.data;
    const edgeData = edgeCtx.createImageData(width, height);
    const edgePixels = edgeData.data;

    // Helper function to get the grayscale value of a pixel, handling image boundaries.
    const getPixel = (x, y) => {
        if (x < 0 || x >= width || y < 0 || y >= height) {
            return 0; // Return black for out-of-bounds pixels
        }
        // Return the red channel value (since it's grayscale, R=G=B)
        return grayData[(y * width + x) * 4];
    };

    // Sobel operator kernels for edge detection.
    const kernelX = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ];
    const kernelY = [
        [-1, -2, -1],
        [0, 0, 0],
        [1, 2, 1]
    ];

    // Apply the Sobel filter to find edges.
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            let pixelX = 0;
            let pixelY = 0;

            for (let j = -1; j <= 1; j++) {
                for (let i = -1; i <= 1; i++) {
                    const val = getPixel(x + i, y + j);
                    pixelX += val * kernelX[j + 1][i + 1];
                    pixelY += val * kernelY[j + 1][i + 1];
                }
            }

            const magnitude = Math.sqrt(pixelX * pixelX + pixelY * pixelY);
            const destIndex = (y * width + x) * 4;

            if (magnitude > edgeThreshold) {
                // This pixel is an edge, draw it with the specified edge color.
                edgePixels[destIndex] = r;
                edgePixels[destIndex + 1] = g;
                edgePixels[destIndex + 2] = b;
                edgePixels[destIndex + 3] = 255; // Opaque
            } else {
                // This pixel is not an edge, make it transparent.
                edgePixels[destIndex + 3] = 0;
            }
        }
    }
    edgeCtx.putImageData(edgeData, 0, 0);


    // --- Step 3: Combine the layers ---
    // Draw the posterized color layer first.
    ctx.drawImage(colorCanvas, 0, 0);
    // Draw the detected edges on top.
    ctx.drawImage(edgeCanvas, 0, 0);

    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 From Photo tool allows users to transform standard images into cartoon-style illustrations. By applying techniques such as color posterization and edge detection, this tool creates a stylized effect reminiscent of animated art. Users can customize the degree of color simplification, the amount of blur applied for smoother transitions, and the sensitivity of edge detection. This tool is ideal for creating playful and artistic renditions of photos, making it suitable for graphic design, social media content, and personal projects that aim for a fun or whimsical aesthetic.

Leave a Reply

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