Please bookmark this page to avoid losing your image tool!

Favorite Cartoon Image Creator

(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.
function processImage(originalImg, colorLevels = 6, edgeThreshold = 80, blurRadius = 2) {
    // Parse parameters
    colorLevels = Number(colorLevels) || 6;
    edgeThreshold = Number(edgeThreshold) || 80;
    blurRadius = Number(blurRadius) || 2;

    const width = originalImg.width;
    const height = originalImg.height;

    // Main canvas to store the final output
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Secondary canvas for blurred and saturated color base
    const blurCanvas = document.createElement('canvas');
    blurCanvas.width = width;
    blurCanvas.height = height;
    const blurCtx = blurCanvas.getContext('2d', { willReadFrequently: true });
    
    // Apply CSS filters: blur removes small details and saturate boosts colors
    blurCtx.filter = `blur(${blurRadius}px) saturate(150%)`;
    blurCtx.drawImage(originalImg, 0, 0, width, height);

    const blurImgData = blurCtx.getImageData(0, 0, width, height);
    const data = blurImgData.data;

    // Apply Posterization (reducing color depth / "Cel Shading" effect)
    const levelSize = 255 / colorLevels;
    for (let i = 0; i < data.length; i += 4) {
        data[i] = Math.round(data[i] / levelSize) * levelSize;
        data[i + 1] = Math.round(data[i + 1] / levelSize) * levelSize;
        data[i + 2] = Math.round(data[i + 2] / levelSize) * levelSize;
    }

    // Draw the unblurred original image onto the main canvas temporarily
    // to secure precise grayscale information for the edge detection
    ctx.drawImage(originalImg, 0, 0, width, height);
    const origData = ctx.getImageData(0, 0, width, height).data;

    // Prepare grayscale mapped array
    const gray = new Uint8Array(width * height);
    for (let i = 0; i < origData.length; i += 4) {
        const r = origData[i];
        const g = origData[i + 1];
        const b = origData[i + 2];
        const a = origData[i + 3] / 255;
        
        // Blend with white background to handle transparency
        const blendedR = r * a + 255 * (1 - a);
        const blendedG = g * a + 255 * (1 - a);
        const blendedB = b * a + 255 * (1 - a);
        
        gray[i / 4] = 0.299 * blendedR + 0.587 * blendedG + 0.114 * blendedB;
    }

    // Edge Detection using Sobel operator on grayscale image
    // Inner loops are unrolled to optimize processing speeds on larger images
    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            const idx = y * width + x;
            
            const i00 = idx - width - 1, i01 = idx - width, i02 = idx - width + 1;
            const i10 = idx - 1,                            i12 = idx + 1;
            const i20 = idx + width - 1, i21 = idx + width, i22 = idx + width + 1;

            const g00 = gray[i00], g01 = gray[i01], g02 = gray[i02];
            const g10 = gray[i10],                  g12 = gray[i12];
            const g20 = gray[i20], g21 = gray[i21], g22 = gray[i22];

            // Sobel Kernel Matrix X
            const px = -g00 + g02 - 2 * g10 + 2 * g12 - g20 + g22;
            // Sobel Kernel Matrix Y
            const py = -g00 - 2 * g01 - g02 + g20 + 2 * g21 + g22;

            const magnitude = Math.sqrt(px * px + py * py);
            
            // If the edge gradient is larger than defined threshold, draw an outline
            if (magnitude > edgeThreshold) {
                const imgIdx = idx * 4;
                if (data[imgIdx + 3] > 0) { // Do not draw edges over purely transparent pixels
                    data[imgIdx] = 0;     // R
                    data[imgIdx + 1] = 0; // G
                    data[imgIdx + 2] = 0; // B
                }
            }
        }
    }

    // Push combined image data rendering back onto the main canvas
    ctx.putImageData(blurImgData, 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 Favorite Cartoon Image Creator is an image processing tool that transforms standard photographs into stylized cartoon-like illustrations. It achieves this effect by applying a cel-shading technique through color posterization, increasing color saturation, and applying a subtle blur to smooth out textures. Additionally, the tool uses edge detection to add bold black outlines around subjects, mimicking a hand-drawn animation style. This tool is ideal for creative social media profiles, making personalized avatars, or adding an artistic, illustrative touch to personal photos.

Leave a Reply

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