Please bookmark this page to avoid losing your image tool!

Image Metallic Filter Application

(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, color = "silver", contrast = 1.5, strength = 0.8) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // Opt-in for performance if available

    // Ensure originalImg is loaded and has dimensions
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    if (!imgWidth || !imgHeight) {
        console.error("Image has no dimensions or is not loaded properly.");
        // Return an empty canvas or draw an error message
        canvas.width = 100; // Default error canvas size
        canvas.height = 50;
        ctx.fillStyle = 'red';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'white';
        ctx.font = '12px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('Invalid Image', canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    
    canvas.width = imgWidth;
    canvas.height = imgHeight;

    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // Handle potential security errors (e.g., cross-origin image)
        console.error("Error getting ImageData:", e);
        // Return canvas with an error message drawn
        ctx.clearRect(0,0, canvas.width, canvas.height); // Clear drawn image if it was from a tainted source
        ctx.fillStyle = 'lightgray';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'black';
        ctx.font = '16px Arial';
        ctx.textAlign = 'center';
        let msg = 'Error: Could not process image.';
        if (e.name === 'SecurityError') {
            msg = 'Error: Cross-origin image security.';
        }
        const lines = msg.split('\n');
        for(let i = 0; i < lines.length; i++) {
            ctx.fillText(lines[i], canvas.width / 2, canvas.height / 2 - (lines.length-1)*8 + i*16);
        }
        return canvas;
    }
    
    const data = imageData.data;

    let tintR = 1.0, tintG = 1.0, tintB = 1.0; // Default for "silver"

    const lowerCaseColor = String(color).toLowerCase();

    if (lowerCaseColor === "gold") {
        tintR = 1.0;    // R: 255
        tintG = 215/255;  // G: 215
        tintB = 0/255;    // B: 0
    } else if (lowerCaseColor === "copper") {
        tintR = 184/255;  // R: 184
        tintG = 115/255;  // G: 115
        tintB = 51/255;   // B: 51
    } else if (lowerCaseColor.startsWith("#")) {
        const hex = lowerCaseColor.substring(1);
        if (/^[0-9a-f]{6}$/.test(hex)) { // Match #RRGGBB
            tintR = parseInt(hex.substring(0, 2), 16) / 255;
            tintG = parseInt(hex.substring(2, 4), 16) / 255;
            tintB = parseInt(hex.substring(4, 6), 16) / 255;
        } else if (/^[0-9a-f]{3}$/.test(hex)) { // Match #RGB
            tintR = parseInt(hex.substring(0, 1) + hex.substring(0, 1), 16) / 255;
            tintG = parseInt(hex.substring(1, 2) + hex.substring(1, 2), 16) / 255;
            tintB = parseInt(hex.substring(2, 3) + hex.substring(2, 3), 16) / 255;
        }
        // If hex is invalid, tint remains silver (1.0, 1.0, 1.0) as initialized
    }

    // Clamp parameters to sensible ranges
    const effectiveContrast = Math.max(0, contrast); // Contrast factor shouldn't be negative
    const effectiveStrength = Math.max(0, Math.min(1, strength)); // Strength must be [0, 1]

    for (let i = 0; i < data.length; i += 4) {
        const r_orig = data[i];
        const g_orig = data[i + 1];
        const b_orig = data[i + 2];

        // 1. Grayscale conversion (luminance)
        const luminance = 0.299 * r_orig + 0.587 * g_orig + 0.114 * b_orig;

        // 2. Contrast adjustment
        const normLum = luminance / 255; // Normalize to [0, 1]
        // Apply contrast formula: y = factor * (x - 0.5) + 0.5
        let contrastedLumNorm = (normLum - 0.5) * effectiveContrast + 0.5;
        contrastedLumNorm = Math.max(0, Math.min(1, contrastedLumNorm)); // Clamp to [0, 1]
        const contrastedLum = contrastedLumNorm * 255; // Scale back to [0, 255]

        // 3. Apply tint to the contrasted luminance
        const procR = contrastedLum * tintR;
        const procG = contrastedLum * tintG;
        const procB = contrastedLum * tintB;

        // 4. Blend with original pixel based on strength
        const finalR = (1 - effectiveStrength) * r_orig + effectiveStrength * procR;
        const finalG = (1 - effectiveStrength) * g_orig + effectiveStrength * procG;
        const finalB = (1 - effectiveStrength) * b_orig + effectiveStrength * procB;

        // 5. Assign clamped values back to imageData
        data[i]     = Math.max(0, Math.min(255, Math.round(finalR)));
        data[i + 1] = Math.max(0, Math.min(255, Math.round(finalG)));
        data[i + 2] = Math.max(0, Math.min(255, Math.round(finalB)));
        // 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 Image Metallic Filter Application is a tool that allows users to apply a metallic filter effect to images. Users can choose from different metallic colors such as silver, gold, and copper, or even specify a custom color using a hex code. The app allows for adjustments in contrast and strength of the effect, enabling users to refine the metallic appearance to their liking. This tool is ideal for enhancing images in graphic design projects, creating eye-catching social media posts, or adding a unique touch to digital artwork.

Leave a Reply

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