Please bookmark this page to avoid losing your image tool!

Photo Recoloring 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, recolorType = 'sepia', tintColor = '#FFFF00') {
    // Helper function for hex to RGB conversion.
    // It's defined within processImage to keep it self-contained.
    function hexToRgb(hex) {
        if (typeof hex !== 'string') {
            return null;
        }
        // Remove # if present
        let c = hex.startsWith('#') ? hex.substring(1) : hex;

        // Expand shorthand form (e.g., "03F") to full form (e.g., "0033FF")
        if (c.length === 3) {
            c = c[0] + c[0] + c[1] + c[1] + c[2] + c[2];
        }

        // Check if it's a 6-digit hex code
        if (c.length !== 6) {
            return null;
        }

        const r = parseInt(c.substring(0, 2), 16);
        const g = parseInt(c.substring(2, 4), 16);
        const b = parseInt(c.substring(4, 6), 16);

        // Check if parsing was successful (e.g., not NaN)
        if (isNaN(r) || isNaN(g) || isNaN(b)) {
            return null;
        }
        return { r, g, b };
    }

    const canvas = document.createElement('canvas');
    // Use willReadFrequently hint for potential performance optimization with getImageData
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Use naturalWidth/Height for the true image dimensions, fallback to width/height
    // This handles cases where the image might not be a standard HTMLImageElement or not fully loaded
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;
    
    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // If image dimensions are invalid (e.g., image not loaded or invalid image), return empty canvas.
    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Image dimensions are zero. Cannot process image. Returning an empty canvas.");
        return canvas;
    }

    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    // Try-catch block for getImageData as it can throw security errors for cross-origin images
    // if the canvas is tainted.
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Could not get image data. This might be due to cross-origin restrictions if the image source is external and lacks CORS headers.", e);
        // In case of error (e.g. CORS), return the canvas with the original image drawn,
        // as no pixel manipulation can be done.
        return canvas;
    }
    
    const data = imageData.data; // This is a Uint8ClampedArray: R,G,B,A, R,G,B,A, ...

    let parsedTintColor = null;
    if (recolorType === 'tint') {
        parsedTintColor = hexToRgb(tintColor);
        if (!parsedTintColor) {
            // Log a warning if the tintColor is invalid. The 'tint' effect will default to grayscale.
            console.warn(`Invalid tintColor: "${tintColor}". The 'tint' effect will default to grayscale.`);
        }
    }

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];     // Red channel
        const g = data[i + 1]; // Green channel
        const b = data[i + 2]; // Blue channel
        // data[i+3] is Alpha channel, typically left unchanged for these recoloring effects.

        let newR, newG, newB;

        switch (recolorType) {
            case 'grayscale':
                // Standard luminance calculation for grayscale
                const gray = 0.299 * r + 0.587 * g + 0.114 * b;
                newR = gray;
                newG = gray;
                newB = gray;
                break;
            case 'sepia':
                // Standard sepia filter coefficients
                newR = 0.393 * r + 0.769 * g + 0.189 * b;
                newG = 0.349 * r + 0.686 * g + 0.168 * b;
                newB = 0.272 * r + 0.534 * g + 0.131 * b;
                break;
            case 'invert':
                newR = 255 - r;
                newG = 255 - g;
                newB = 255 - b;
                break;
            case 'tint':
                // Convert to grayscale first to get luminance/intensity
                const intensity = 0.299 * r + 0.587 * g + 0.114 * b;
                if (parsedTintColor) {
                    // Apply tint by scaling intensity with normalized tint color components
                    newR = intensity * (parsedTintColor.r / 255);
                    newG = intensity * (parsedTintColor.g / 255);
                    newB = intensity * (parsedTintColor.b / 255);
                } else {
                    // Fallback for invalid or unparsed tintColor: apply grayscale
                    newR = intensity;
                    newG = intensity;
                    newB = intensity;
                }
                break;
            default:
                // If recolorType is unknown or not specified, keep original colors
                newR = r;
                newG = g;
                newB = b;
                if (recolorType !== 'sepia') { // Avoid warning for default 'sepia' if it reaches here due to a bug
                     console.warn(`Unknown recolorType: "${recolorType}". No color transformation applied.`);
                }
                break;
        }

        // Clamp values to the 0-255 range to ensure validity
        data[i] = Math.min(255, Math.max(0, newR));
        data[i + 1] = Math.min(255, Math.max(0, newG));
        data[i + 2] = Math.min(255, Math.max(0, newB));
        // Alpha channel (data[i+3]) remains unchanged
    }

    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 Photo Recoloring Tool allows users to transform images by applying various color effects. Users can choose to apply a grayscale, sepia, inverted, or tinted effect to their images. This tool is ideal for enhancing photos, creating artistic interpretations, or achieving specific aesthetic styles for graphics and social media. It is particularly useful for designers, photographers, and anyone looking to creatively edit images for projects or personal use.

Leave a Reply

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