Please bookmark this page to avoid losing your image tool!

Image Paper Lantern Filter Effect 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.
function processImage(originalImg, lanternColor = "#FFA500", blurAmount = 3, brightness = 1.1, noiseIntensity = 20, tintStrength = 0.5) {
    
    // Helper function to clamp a value between min and max, and round it.
    // Pixel component values must be integers in the range [0, 255].
    const clamp = (value, min = 0, max = 255) => Math.min(Math.max(Math.round(value), min), max);

    // Helper function to parse a hex color string to an [R, G, B] array.
    // Supports #RGB and #RRGGBB formats. Defaults to a shade of orange on error.
    const parseHexColor = (hex) => {
        const hexString = String(hex).replace(/^#/, ''); // Ensure it's a string and remove '#'
        let rHex, gHex, bHex;

        if (hexString.length === 3) { // Expand #RGB to #RRGGBB
            rHex = hexString[0] + hexString[0];
            gHex = hexString[1] + hexString[1];
            bHex = hexString[2] + hexString[2];
        } else if (hexString.length === 6) { // #RRGGBB
            rHex = hexString.substring(0, 2);
            gHex = hexString.substring(2, 4);
            bHex = hexString.substring(4, 6);
        } else {
            // Invalid format, log warning and default to a hardcoded orange
            console.warn(`Invalid lanternColor format: "${hex}". Using default orange #FFA500.`);
            return [255, 165, 0]; 
        }
        
        const r = parseInt(rHex, 16);
        const g = parseInt(gHex, 16);
        const b = parseInt(bHex, 16);

        // Check if parsing resulted in valid numbers
        if (isNaN(r) || isNaN(g) || isNaN(b)) {
            console.warn(`Could not parse hex color components from: "${hexString}". Using default orange #FFA500.`);
            return [255, 165, 0]; 
        }
        return [r, g, b];
    };

    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } can be an optimization hint for frequent getImageData/putImageData calls
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Use naturalWidth/Height for intrinsic dimensions, fallback to width/height
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    // Basic validation for image dimensions
    if (!width || !height || width === 0 || height === 0) {
        console.error("Image has invalid dimensions (e.g., 0 or undefined). Ensure it's properly loaded before processing.");
        // Return a small, clearly marked error canvas to aid debugging
        canvas.width = Math.max(1, 100); // Ensure non-zero width for text
        canvas.height = Math.max(1, 30); // Ensure non-zero height
        ctx.fillStyle = 'red'; 
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'white'; 
        ctx.font = '12px Arial';
        ctx.fillText('Img Error', 5, canvas.height / 2 + 4);
        return canvas;
    }

    canvas.width = width;
    canvas.height = height;

    // Step 1: Apply initial global filters (Blur & Brightness) to the image
    // The ctx.filter property affects subsequent drawing operations.
    let filterValues = [];
    if (brightness !== 1.0) { // brightness(100%) is no-op
        filterValues.push(`brightness(${brightness * 100}%)`);
    }
    if (blurAmount > 0) { // blur(0px) is no-op
        filterValues.push(`blur(${blurAmount}px)`);
    }

    if (filterValues.length > 0) {
        ctx.filter = filterValues.join(' ');
    }
    
    ctx.drawImage(originalImg, 0, 0, width, height);
    ctx.filter = 'none'; // Reset filter to prevent affecting other canvas operations inadvertently

    // Step 2: Apply Color Tint and Noise using pixel-by-pixel manipulation
    // This is done after global filters are applied and the image is drawn.
    const imageData = ctx.getImageData(0, 0, width, height);
    const pixels = imageData.data;
    const [tintR, tintG, tintB] = parseHexColor(lanternColor);

    // Ensure tintStrength is within the valid range [0, 1] for blending
    const currentTintStrength = Math.min(1, Math.max(0, Number(tintStrength) || 0));


    for (let i = 0; i < pixels.length; i += 4) {
        // Get original pixel values (which are already affected by blur/brightness filters)
        let r = pixels[i];
        let g = pixels[i+1];
        let b = pixels[i+2];
        // The alpha channel (pixels[i+3]) is generally preserved unless specified otherwise

        // Apply color tint: R_new = R_old * (1 - strength) + TintColor_R * strength (linear interpolation)
        r = r * (1 - currentTintStrength) + tintR * currentTintStrength;
        g = g * (1 - currentTintStrength) + tintG * currentTintStrength;
        b = b * (1 - currentTintStrength) + tintB * currentTintStrength;
        
        // Noise is applied to the freshly tinted color to simulate paper texture
        // Generates a random noise value (can be positive or negative), scaled by noiseIntensity
        const randomNoise = (Math.random() - 0.5) * noiseIntensity;
        
        // Apply noise and clamp the final RGB values to the 0-255 range
        pixels[i]   = clamp(r + randomNoise);
        pixels[i+1] = clamp(g + randomNoise);
        pixels[i+2] = clamp(b + randomNoise);
    }

    // Write the manipulated pixel data back to the canvas
    ctx.putImageData(imageData, 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 Paper Lantern Filter Effect Tool allows users to apply a unique visual effect to their images, simulating the appearance of being filtered through a paper lantern. This tool lets you adjust settings such as lantern color, blur amount, brightness, noise intensity, and tint strength to achieve the desired aesthetic. It’s ideal for enhancing photos for social media, personal projects, or creative endeavors, giving images an artistic and whimsical touch.

Leave a Reply

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