Please bookmark this page to avoid losing your image tool!

Image Anime Photo 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, posterLevels = 4, saturation = 1.2, edgeThreshold = 80, initialBlurRadius = 0, outlineColorRGB = "0,0,0") {
    // Parameter validation and normalization
    posterLevels = Math.max(2, Math.floor(posterLevels)); 
    saturation = Math.max(0, saturation); 
    edgeThreshold = Math.max(0, Math.min(255, edgeThreshold)); 
    initialBlurRadius = Math.max(0, initialBlurRadius); 
    
    let parsedOutlineColor = outlineColorRGB.split(',').map(Number);
    if (parsedOutlineColor.length !== 3 || parsedOutlineColor.some(val => isNaN(val) || val < 0 || val > 255)) {
        console.warn("Invalid outlineColorRGB format or values. Defaulting to black [0,0,0]. Expected 'r,g,b' with values 0-255.");
        parsedOutlineColor = [0, 0, 0];
    } else {
        parsedOutlineColor = parsedOutlineColor.map(val => Math.floor(Math.max(0, Math.min(255, val))));
    }

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

    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = width;
    outputCanvas.height = height;
    const ctx = outputCanvas.getContext('2d', { willReadFrequently: true });

    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = width;
    tempCanvas.height = height;
    const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });

    // 1. Draw original image to tempCanvas, applying initial blur if specified
    if (initialBlurRadius > 0) {
        tempCtx.filter = `blur(${initialBlurRadius}px)`;
    }
    tempCtx.drawImage(originalImg, 0, 0, width, height);
    if (initialBlurRadius > 0) {
        tempCtx.filter = 'none'; 
    }
    
    const sourceImageData = tempCtx.getImageData(0, 0, width, height);
    const posterizedAndSaturatedData = tempCtx.createImageData(width, height);

    // 2. Posterize and Saturate pass
    const posterizationFactor = posterLevels - 1;
    
    for (let i = 0; i < sourceImageData.data.length; i += 4) {
        let r = sourceImageData.data[i];
        let g = sourceImageData.data[i+1];
        let b = sourceImageData.data[i+2];
        const a = sourceImageData.data[i+3];

        // Posterize
        if (posterizationFactor > 0) { // posterLevels >= 2
            r = Math.round((r / 255) * posterizationFactor) * (255 / posterizationFactor);
            g = Math.round((g / 255) * posterizationFactor) * (255 / posterizationFactor);
            b = Math.round((b / 255) * posterizationFactor) * (255 / posterizationFactor);
        }
        
        r = Math.max(0, Math.min(255, r));
        g = Math.max(0, Math.min(255, g));
        b = Math.max(0, Math.min(255, b));
        
        // Saturate
        if (saturation !== 1.0) {
            const lum = 0.299 * r + 0.587 * g + 0.114 * b;
            r = lum + saturation * (r - lum);
            g = lum + saturation * (g - lum);
            b = lum + saturation * (b - lum);

            r = Math.max(0, Math.min(255, Math.round(r)));
            g = Math.max(0, Math.min(255, Math.round(g)));
            b = Math.max(0, Math.min(255, Math.round(b)));
        }
        
        posterizedAndSaturatedData.data[i]     = r;
        posterizedAndSaturatedData.data[i+1]   = g;
        posterizedAndSaturatedData.data[i+2]   = b;
        posterizedAndSaturatedData.data[i+3]   = a;
    }
    ctx.putImageData(posterizedAndSaturatedData, 0, 0);

    // 3. Edge Detection (Sobel)
    const grayscaleData = tempCtx.createImageData(width, height);
    for (let i = 0; i < sourceImageData.data.length; i += 4) {
        const r_src = sourceImageData.data[i];
        const g_src = sourceImageData.data[i+1];
        const b_src = sourceImageData.data[i+2];
        const gray = Math.round(0.299 * r_src + 0.587 * g_src + 0.114 * b_src);
        grayscaleData.data[i]   = gray;
        grayscaleData.data[i+1] = gray;
        grayscaleData.data[i+2] = gray;
        grayscaleData.data[i+3] = sourceImageData.data[i+3];
    }

    const edgeImageData = tempCtx.createImageData(width, height);
    const Gx = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]];
    const Gy = [[-1, -2, -1], [0, 0, 0], [1, 2, 1]];

    const MAX_SOBEL_MAGNITUDE_APPROX = 1020 * Math.sqrt(2); 
    const normalizationFactor = 255.0 / MAX_SOBEL_MAGNITUDE_APPROX;

    for (let y = 1; y < height - 1; y++) { 
        for (let x = 1; x < width - 1; x++) { 
            let sumX = 0;
            let sumY = 0;

            for (let ky = -1; ky <= 1; ky++) {
                for (let kx = -1; kx <= 1; kx++) {
                    const pixelIndex = ((y + ky) * width + (x + kx)) * 4;
                    const grayVal = grayscaleData.data[pixelIndex];

                    sumX += grayVal * Gx[ky+1][kx+1];
                    sumY += grayVal * Gy[ky+1][kx+1];
                }
            }

            const magnitude = Math.sqrt(sumX * sumX + sumY * sumY);
            const normalizedMagnitude = magnitude * normalizationFactor; 
            
            const outputIndex = (y * width + x) * 4;
            if (normalizedMagnitude > edgeThreshold) {
                edgeImageData.data[outputIndex]   = parsedOutlineColor[0];
                edgeImageData.data[outputIndex+1] = parsedOutlineColor[1];
                edgeImageData.data[outputIndex+2] = parsedOutlineColor[2];
                edgeImageData.data[outputIndex+3] = 255; 
            } else {
                edgeImageData.data[outputIndex + 3] = 0; // Transparent for non-edges
            }
        }
    }
    
    tempCtx.putImageData(edgeImageData, 0, 0);
    ctx.drawImage(tempCanvas, 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 Anime Photo Filter tool allows users to transform their images into a stylized anime art form. By adjusting parameters such as posterization levels, color saturation, edge detection thresholds, and blur radius, users can create unique visual effects that enhance the artistic quality of their photos. This tool is ideal for artists, designers, and anyone looking to add a creative flair to their images, making it suitable for social media posts, creating anime-inspired artwork, or just for fun.

Leave a Reply

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