Please bookmark this page to avoid losing your image tool!

Image Union Multimedia Enhancement Tool

(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.
async function processImage(originalImg, posterizationLevels = 6, outlineStrength = 1.2, outlineColor = '#302010', saturation = 0.8, sepia = 0.2, grainAmount = 0.1) {
    // Clamp parameters to reasonable ranges for stability and quality
    const pLevels = Math.max(2, Math.min(255, Math.floor(posterizationLevels)));
    const sStrength = Math.max(0, outlineStrength);
    const sat = Math.max(0, saturation);
    const sep = Math.max(0, Math.min(1, sepia));
    const grain = Math.max(0, Math.min(1, grainAmount));
    const edgeThreshold = 50;

    // --- 1. Canvas Setup ---
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;

    // Draw image to get pixel data
    ctx.drawImage(originalImg, 0, 0, width, height);
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;
    const originalData = Uint8ClampedArray.from(data); // Create an unmodified copy for edge detection

    // --- 2. Color Processing (Posterize, Sepia, Saturate) ---
    // This loop applies the core color palette reduction and vintage tinting
    const step = 255 / (pLevels - 1);
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];

        // Posterize: Reduce the number of colors for a cartoon look
        r = Math.round(r / step) * step;
        g = Math.round(g / step) * step;
        b = Math.round(b / step) * step;

        // Sepia: Add a warm, aged tint
        if (sep > 0) {
            const sr = r * (1 - 0.607 * sep) + g * (0.769 * sep) + b * (0.189 * sep);
            const sg = r * (0.349 * sep) + g * (1 - 0.314 * sep) + b * (0.168 * sep);
            const sb = r * (0.272 * sep) + g * (0.534 * sep) + b * (1 - 0.869 * sep);
            r = sr; g = sg; b = sb;
        }

        // Saturation: Mute the colors for a classic feel
        if (sat !== 1) {
            const gray = 0.299 * r + 0.587 * g + 0.114 * b;
            r = gray * (1 - sat) + r * sat;
            g = gray * (1 - sat) + g * sat;
            b = gray * (1 - sat) + b * sat;
        }

        data[i] = r;
        data[i + 1] = g;
        data[i + 2] = b;
    }
    ctx.putImageData(imageData, 0, 0);

    // --- 3. Edge Detection (Sobel) for Outlines ---
    // Creates the hand-drawn outline effect typical of cel animation
    if (sStrength > 0) {
        const outlineCanvas = document.createElement('canvas');
        outlineCanvas.width = width;
        outlineCanvas.height = height;
        const outlineCtx = outlineCanvas.getContext('2d');

        const rC = parseInt(outlineColor.slice(1, 3), 16);
        const gC = parseInt(outlineColor.slice(3, 5), 16);
        const bC = parseInt(outlineColor.slice(5, 7), 16);

        const getIntensity = (d, x, y, w) => {
            const i = (y * w + x) * 4;
            // Luminosity method for grayscale conversion
            return 0.299 * d[i] + 0.587 * d[i + 1] + 0.114 * d[i + 2];
        };

        const sobelX = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]];
        const sobelY = [[-1, -2, -1], [0, 0, 0], [1, 2, 1]];

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

                for (let j = -1; j <= 1; j++) {
                    for (let i = -1; i <= 1; i++) {
                        const intensity = getIntensity(originalData, x + i, y + j, width);
                        pixelX += intensity * sobelX[j + 1][i + 1];
                        pixelY += intensity * sobelY[j + 1][i + 1];
                    }
                }

                const magnitude = Math.sqrt(pixelX * pixelX + pixelY * pixelY);

                if (magnitude > edgeThreshold) {
                    const opacity = Math.min(1, magnitude / 150);
                    outlineCtx.fillStyle = `rgba(${rC}, ${gC}, ${bC}, ${opacity})`;
                    
                    // Add random wobble to simulate hand-drawn imperfection
                    const wobbleX = (Math.random() - 0.5) * sStrength;
                    const wobbleY = (Math.random() - 0.5) * sStrength;
                    
                    // Draw a small circle for each edge pixel to build up the line
                    outlineCtx.beginPath();
                    outlineCtx.arc(x + wobbleX, y + wobbleY, sStrength / 2, 0, Math.PI * 2);
                    outlineCtx.fill();
                }
            }
        }
        ctx.drawImage(outlineCanvas, 0, 0);
    }
    
    // --- 4. Grain / Texture Overlay ---
    // Adds a subtle paper or film grain texture
    if (grain > 0) {
        const grainCanvas = document.createElement('canvas');
        grainCanvas.width = width;
        grainCanvas.height = height;
        const grainCtx = grainCanvas.getContext('2d');
        const grainImageData = grainCtx.createImageData(width, height);
        const grainData = grainImageData.data;

        for (let i = 0; i < grainData.length; i += 4) {
             const val = Math.random() * 255;
             grainData[i] = val;
             grainData[i+1] = val;
             grainData[i+2] = val;
             grainData[i+3] = 255;
        }
        grainCtx.putImageData(grainImageData, 0, 0);

        ctx.globalAlpha = grain;
        ctx.globalCompositeOperation = 'soft-light';
        ctx.drawImage(grainCanvas, 0, 0);
        
        // Reset canvas context properties
        ctx.globalAlpha = 1.0;
        ctx.globalCompositeOperation = 'source-over';
    }

    // --- 5. Return Final Canvas ---
    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 Union Multimedia Enhancement Tool allows users to process images by applying various artistic enhancements such as posterization, sepia toning, color saturation adjustments, and edge detection for outlining. It is ideal for those looking to create a stylized or vintage look for their images, such as for art projects, graphic design, and social media displays. The tool supports options for customizing outline strength and color, along with adding grain for texture, enabling users to produce unique and visually appealing image effects.

Leave a Reply

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