Please bookmark this page to avoid losing your image tool!

Image Cartoon Effect Filter

(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, levels = 6, edgeThreshold = 80, edgeR = 0, edgeG = 0, edgeB = 0) {
    // Helper function for color quantization
    function quantizeChannel(value, numLevels) {
        if (numLevels <= 1) { // Binary (black or white based on midpoint)
            return value < 128 ? 0 : 255;
        }
        // Calculate the size of each quantization step
        const step = 255.0 / (numLevels - 1);
        // Quantize the value by finding the nearest step
        return Math.round(value / step) * step;
    }

    // Sobel kernels for edge detection
    const sobelXKernel = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ];
    const sobelYKernel = [
        [-1, -2, -1],
        [ 0,  0,  0],
        [ 1,  2,  1]
    ];

    // 0. Parameter validation/sanitization
    levels = Math.max(1, Math.floor(levels)); // Ensure levels is at least 1
    edgeThreshold = Math.max(0, edgeThreshold); // Non-negative threshold
    edgeR = Math.max(0, Math.min(255, Math.floor(edgeR))); // Clamp edge color components
    edgeG = Math.max(0, Math.min(255, Math.floor(edgeG)));
    edgeB = Math.max(0, Math.min(255, Math.floor(edgeB)));

    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    if (width === 0 || height === 0) {
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = width; // which is 0
        emptyCanvas.height = height; // which is 0
        return emptyCanvas; // Return empty canvas for 0-size image
    }

    // 1. Canvas setup & Get Image Data
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // Optimization hint
    ctx.drawImage(originalImg, 0, 0, width, height);
    
    let imgData;
    try {
        imgData = ctx.getImageData(0, 0, width, height);
    } catch (e) {
        // Handle potential security errors if image is cross-origin and canvas is tainted
        console.error("Error getting ImageData:", e);
        // Fallback: return the original image drawn on a canvas if processing fails
        const fallbackCanvas = document.createElement('canvas');
        fallbackCanvas.width = width;
        fallbackCanvas.height = height;
        const fallbackCtx = fallbackCanvas.getContext('2d');
        fallbackCtx.drawImage(originalImg, 0, 0, width, height);
        return fallbackCanvas;
    }
    const data = imgData.data; // Uint8ClampedArray of [R,G,B,A, R,G,B,A, ...]

    // 2. Grayscale Conversion
    const grayData = new Uint8Array(width * height); // Stores intensity (0-255)
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i+1];
        const b = data[i+2];
        // Standard luminance calculation: (0.299*R + 0.587*G + 0.114*B)
        grayData[i / 4] = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
    }

    // 3. Sobel Edge Detection & Thresholding
    const isEdge = new Uint8Array(width * height); // 1 if edge, 0 otherwise. Zero-initialized.
    // Iterate, skipping 1-pixel border to avoid out-of-bounds access in kernel
    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            let gx = 0;
            let gy = 0;

            // Apply Sobel kernels centered at (x,y)
            for (let ky = -1; ky <= 1; ky++) { // Kernel Y offset
                for (let kx = -1; kx <= 1; kx++) { // Kernel X offset
                    // Pixel value from grayscale image at (x+kx, y+ky)
                    const currentPixelGrayscale = grayData[(y + ky) * width + (x + kx)];
                    gx += currentPixelGrayscale * sobelXKernel[ky + 1][kx + 1];
                    gy += currentPixelGrayscale * sobelYKernel[ky + 1][kx + 1];
                }
            }

            const magnitude = Math.sqrt(gx * gx + gy * gy);
            if (magnitude > edgeThreshold) {
                isEdge[y * width + x] = 1;
            }
        }
    }

    // 4. Final Pixel Composition
    const outputPixelData = new Uint8ClampedArray(data.length);
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const pixelIndex = y * width + x; // Index for 1D arrays (grayData, isEdge)
            const dataIndex = pixelIndex * 4;   // Index for RGBA pixel data arrays (data, outputPixelData)

            if (isEdge[pixelIndex] === 1) { // Check if current pixel is marked as an edge
                outputPixelData[dataIndex]     = edgeR;
                outputPixelData[dataIndex + 1] = edgeG;
                outputPixelData[dataIndex + 2] = edgeB;
                outputPixelData[dataIndex + 3] = 255; // Edges are opaque black (or specified edge color)
            } else {
                // Not an edge, apply color quantization
                outputPixelData[dataIndex]     = quantizeChannel(data[dataIndex], levels);
                outputPixelData[dataIndex + 1] = quantizeChannel(data[dataIndex + 1], levels);
                outputPixelData[dataIndex + 2] = quantizeChannel(data[dataIndex + 2], levels);
                outputPixelData[dataIndex + 3] = data[dataIndex + 3]; // Preserve original alpha
            }
        }
    }

    // 5. Return Canvas
    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = width;
    outputCanvas.height = height;
    const outputCtx = outputCanvas.getContext('2d');
    const finalImageData = new ImageData(outputPixelData, width, height);
    outputCtx.putImageData(finalImageData, 0, 0);

    return outputCanvas;
}

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 Cartoon Effect Filter is a web-based tool designed to enhance images by applying a cartoon-like effect. This tool processes your images by reducing color detail through quantization and enhancing edges, which gives a unique, artistic appearance. It’s particularly useful for artists, graphic designers, and anyone looking to transform photographs into eye-catching cartoon-style graphics for social media, promotional materials, or personal projects.

Leave a Reply

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