Please bookmark this page to avoid losing your image tool!

Image HDR Filtering 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, amount = 1.0, radius = 3, saturation = 1.2, gamma = 1.0) {

    // Helper function to clamp values between min and max
    function clamp(value, min, max) {
        return Math.max(min, Math.min(value, max));
    }

    // Helper function to convert RGB to HSL
    // r, g, b are in [0, 255]
    // returns h, s, l in [0, 1]
    function rgbToHsl(r, g, b) {
        r /= 255; g /= 255; b /= 255;
        const max = Math.max(r, g, b), min = Math.min(r, g, b);
        let h, s, l = (max + min) / 2;

        if (max === min) {
            h = s = 0; // achromatic
        } else {
            const d = max - min;
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
            switch (max) {
                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                case g: h = (b - r) / d + 2; break;
                case b: h = (r - g) / d + 4; break;
            }
            h /= 6;
        }
        return [h, s, l];
    }

    // Helper function to convert HSL to RGB
    // h, s, l are in [0, 1]
    // returns r, g, b in [0, 255]
    function hslToRgb(h, s, l) {
        let r, g, b;

        if (s === 0) {
            r = g = b = l; // achromatic
        } else {
            const hue2rgb = (p, q, t) => {
                if (t < 0) t += 1;
                if (t > 1) t -= 1;
                if (t < 1 / 6) return p + (q - p) * 6 * t;
                if (t < 1 / 2) return q;
                if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
                return p;
            };
            const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            const p = 2 * l - q;
            r = hue2rgb(p, q, h + 1 / 3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1 / 3);
        }
        return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }

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

    if (!originalImg || width === 0 || height === 0) {
        // Handle cases where image might not be loaded or has no dimensions
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = 0;
        emptyCanvas.height = 0;
        return emptyCanvas;
    }
    
    // Sanitize parameters
    amount = Math.max(0, amount);
    radius = Math.max(0, radius);
    saturation = Math.max(0, saturation);
    // gamma will be checked later to ensure it's > 0 before Math.pow

    const resultCanvas = document.createElement('canvas');
    resultCanvas.width = width;
    resultCanvas.height = height;
    const resultCtx = resultCanvas.getContext('2d');

    // Draw original image to a temporary working canvas to get its ImageData
    const workingCanvas = document.createElement('canvas');
    workingCanvas.width = width;
    workingCanvas.height = height;
    const workingCtx = workingCanvas.getContext('2d', { willReadFrequently: true });
    workingCtx.drawImage(originalImg, 0, 0, width, height);
    
    const currentImageData = workingCtx.getImageData(0, 0, width, height);
    const pixels = currentImageData.data;

    // --- Unsharp Masking (Detail Enhancement) ---
    if (amount > 0 && radius > 0) {
        const originalPixelsCopy = new Uint8ClampedArray(pixels); 

        const blurEffectCanvas = document.createElement('canvas');
        blurEffectCanvas.width = width;
        blurEffectCanvas.height = height;
        const blurEffectCtx = blurEffectCanvas.getContext('2d', { willReadFrequently: true });
        
        blurEffectCtx.filter = `blur(${radius}px)`;
        blurEffectCtx.drawImage(originalImg, 0, 0, width, height);

        const tempCanvasForBlurredData = document.createElement('canvas');
        tempCanvasForBlurredData.width = width;
        tempCanvasForBlurredData.height = height;
        const tempCtxBlurred = tempCanvasForBlurredData.getContext('2d', { willReadFrequently: true });
        tempCtxBlurred.drawImage(blurEffectCanvas, 0, 0, width, height);
        const blurredPixelsData = tempCtxBlurred.getImageData(0, 0, width, height).data;

        for (let i = 0; i < pixels.length; i += 4) {
            const detailR = originalPixelsCopy[i] - blurredPixelsData[i];
            const detailG = originalPixelsCopy[i + 1] - blurredPixelsData[i + 1];
            const detailB = originalPixelsCopy[i + 2] - blurredPixelsData[i + 2];

            pixels[i]     = clamp(originalPixelsCopy[i]     + amount * detailR, 0, 255);
            pixels[i + 1] = clamp(originalPixelsCopy[i + 1] + amount * detailG, 0, 255);
            pixels[i + 2] = clamp(originalPixelsCopy[i + 2] + amount * detailB, 0, 255);
        }
    }

    // --- Saturation Adjustment ---
    if (saturation !== 1.0) { // Avoid processing if no change
        for (let i = 0; i < pixels.length; i += 4) {
            let r = pixels[i];
            let g = pixels[i + 1];
            let b = pixels[i + 2];

            let [h, s, l] = rgbToHsl(r, g, b);
            s = clamp(s * saturation, 0, 1);
            [r, g, b] = hslToRgb(h, s, l);

            pixels[i] = r;
            pixels[i + 1] = g;
            pixels[i + 2] = b;
        }
    }

    // --- Gamma Correction ---
    if (gamma !== 1.0 && gamma > 0) { // Ensure gamma is positive and there's a change
        const invGamma = 1.0 / gamma;
        for (let i = 0; i < pixels.length; i += 4) {
            pixels[i]     = clamp(Math.round(Math.pow(pixels[i] / 255, invGamma) * 255), 0, 255);
            pixels[i + 1] = clamp(Math.round(Math.pow(pixels[i + 1] / 255, invGamma) * 255), 0, 255);
            pixels[i + 2] = clamp(Math.round(Math.pow(pixels[i + 2] / 255, invGamma) * 255), 0, 255);
        }
    }

    resultCtx.putImageData(currentImageData, 0, 0);

    return resultCanvas;
}

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 HDR Filtering Tool enhances your images by simulating high dynamic range (HDR) effects. It allows users to adjust various parameters such as detail enhancement, saturation, and gamma correction to create visually striking images. This tool is particularly useful for photographers, graphic designers, and content creators looking to improve their images’ quality for web use, presentations, or print. By applying unsharp masking, adjusting color saturation, and correcting gamma, users can make their images appear more vibrant and richly detailed.

Leave a Reply

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