Please bookmark this page to avoid losing your image tool!

Image Color Grading Filter For Various Moods

(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, mood = "normal") {
    const canvas = document.createElement('canvas');
    // Use willReadFrequently for potential performance improvement if this function is called often
    // or on large images, though for a single call its impact might be minimal.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

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

    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // If image has no dimensions (e.g., not loaded or invalid), return an empty canvas.
    if (!imgWidth || !imgHeight) {
        return canvas;
    }

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

    // Ensure mood is a string before calling toLowerCase, defaulting to "normal" if not.
    const lowerCaseMood = (typeof mood === 'string' ? mood.toLowerCase() : "normal");

    // If mood is "normal", no processing is needed, return canvas with original image.
    if (lowerCaseMood === "normal") {
        return canvas;
    }

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        // This can happen due to tainted canvas (e.g., if image is cross-origin and
        // server doesn't provide appropriate CORS headers).
        // In such a case, pixel manipulation is not possible.
        // Returning the canvas with the original image drawn is a fallback.
        // Consider logging `e` for debugging in a real application.
        return canvas;
    }
    
    const data = imageData.data;

    // Helper function to clamp color values to the 0-255 range and round them.
    const clamp = (value) => Math.max(0, Math.min(255, Math.round(value)));

    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];
        // Alpha channel (data[i+3]) is typically preserved in color grading.

        // Variables used by multiple filters
        let lum, desatFactor, contrastFactor; 

        switch (lowerCaseMood) {
            case "sepia":
                // Standard sepia formula
                const tr = 0.393 * r + 0.769 * g + 0.189 * b;
                const tg = 0.349 * r + 0.686 * g + 0.168 * b;
                const tb = 0.272 * r + 0.534 * g + 0.131 * b;
                data[i] = clamp(tr);
                data[i + 1] = clamp(tg);
                data[i + 2] = clamp(tb);
                break;
            case "grayscale":
            case "bw": // Alias for grayscale
                lum = 0.299 * r + 0.587 * g + 0.114 * b; // Luminosity method
                data[i] = clamp(lum);
                data[i + 1] = clamp(lum);
                data[i + 2] = clamp(lum);
                break;
            case "invert":
                data[i] = 255 - r;
                data[i + 1] = 255 - g;
                data[i + 2] = 255 - b;
                break;
            case "vintage":
                lum = 0.299 * r + 0.587 * g + 0.114 * b;
                desatFactor = 0.35; // Desaturation amount
                let rV = r * (1 - desatFactor) + lum * desatFactor;
                let gV = g * (1 - desatFactor) + lum * desatFactor;
                let bV = b * (1 - desatFactor) + lum * desatFactor;

                const brightnessFactorV = 0.96; // Slight dimming
                data[i] = clamp((rV + 22) * brightnessFactorV); // Add yellow/brown tones
                data[i + 1] = clamp((gV + 12) * brightnessFactorV);
                data[i + 2] = clamp((bV - 8) * brightnessFactorV);  // Reduce blue component
                break;
            case "cool_filter": // Emphasize blues, reduce warmth
                data[i] = clamp(r * 0.88); // Reduce red
                data[i + 1] = clamp(g * 0.94); // Shift green towards cyan/cool
                data[i + 2] = clamp(b * 1.18); // Boost blue
                break;
            case "warm_filter": // Emphasize reds/oranges, reduce coolness
                data[i] = clamp(r * 1.18); // Boost red
                data[i + 1] = clamp(g * 1.07); // Boost green slightly for warmer yellows/oranges
                data[i + 2] = clamp(b * 0.88); // Reduce blue
                break;
            case "high_contrast":
                contrastFactor = 1.6; // Amount of contrast increase
                data[i] = clamp(128 + contrastFactor * (r - 128));
                data[i + 1] = clamp(128 + contrastFactor * (g - 128));
                data[i + 2] = clamp(128 + contrastFactor * (b - 128));
                break;
            case "muted_tones": // Desaturate and slightly lower contrast
                lum = 0.299 * r + 0.587 * g + 0.114 * b;
                desatFactor = 0.55; // Significant desaturation
                let rM = r * (1 - desatFactor) + lum * desatFactor;
                let gM = g * (1 - desatFactor) + lum * desatFactor;
                let bM = b * (1 - desatFactor) + lum * desatFactor;

                contrastFactor = 0.80; // Reduce contrast
                data[i] = clamp(128 + contrastFactor * (rM - 128));
                data[i + 1] = clamp(128 + contrastFactor * (gM - 128));
                data[i + 2] = clamp(128 + contrastFactor * (bM - 128));
                break;
            case "noir": // High contrast grayscale, classic film noir style
                lum = 0.299 * r + 0.587 * g + 0.114 * b;
                contrastFactor = 1.9; // Strong contrast
                const valN = clamp(128 + contrastFactor * (lum - 128));
                data[i] = valN;
                data[i + 1] = valN;
                data[i + 2] = valN;
                break;
            case "sunny_day": // Bright, saturated, warm
                lum = 0.299 * r + 0.587 * g + 0.114 * b;
                const satFactorS = 1.22; // Increase saturation
                let rS = clamp(lum + satFactorS * (r - lum));
                let gS = clamp(lum + satFactorS * (g - lum));
                let bS = clamp(lum + satFactorS * (b - lum));

                const brightnessS = 1.04; // Slight brightness boost
                data[i] = clamp(rS * 1.10 * brightnessS); // Warmer reds
                data[i + 1] = clamp(gS * 1.05 * brightnessS); // Warmer greens/yellows
                data[i + 2] = clamp(bS * 0.94 * brightnessS); // Slightly reduce blue to enhance warmth
                break;
            default:
                // If mood is unknown, pixels are not changed.
                // The original image (drawn initially) will be on the canvas.
                break;
        }
    }

    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 Color Grading Filter for Various Moods is a web-based tool that enables users to apply different color grading filters to their images, enhancing the mood and aesthetic of photos. Users can choose from various presets such as sepia, grayscale, vintage, cool, warm, and more to achieve the desired effect. This tool is ideal for photographers, digital artists, and anyone looking to improve their images for social media, personal projects, or professional use by providing a simple way to manipulate the emotional tone of their visuals.

Leave a Reply

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