Please bookmark this page to avoid losing your image tool!

Image Sepia 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.
async function processImage(originalImg) {
    try {
        // Ensure the image is loaded. HTMLImageElement.decode() returns a Promise
        // that resolves when the image is decoded and ready for use.
        // It handles cases like src not being set, or image failing to load.
        // For an Image object, .src must be set. For an <img> element, the src attribute must be set.
        await originalImg.decode();
    } catch (error) {
        console.error("Error loading/decoding image:", error);
        // Create a canvas to display an error message       
        const errorCanvas = document.createElement('canvas');
        // Dimensions for the error message canvas
        const errWidth = 250; 
        const errHeight = 60;
        errorCanvas.width = errWidth;
        errorCanvas.height = errHeight;
        const errorCtx = errorCanvas.getContext('2d');

        errorCtx.fillStyle = '#F0F0F0'; // Light gray background
        errorCtx.fillRect(0, 0, errWidth, errHeight);
        
        errorCtx.fillStyle = '#D8000C'; // Red color for error text
        errorCtx.font = 'bold 14px Arial, sans-serif';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        
        let displayMessage = "Error loading image.";
        if (error.message) { // Check if error.message exists
            const lowerCaseMsg = error.message.toLowerCase();
            if (lowerCaseMsg.includes("source") || lowerCaseMsg.includes("empty")) {
                displayMessage = "Image source invalid or not found.";
            } else if (lowerCaseMsg.includes("decode")) {
                displayMessage = "Could not decode image.";
            }
        }
        
        errorCtx.fillText(displayMessage, errWidth / 2, errHeight / 2);
        return errorCanvas;
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Use naturalWidth and naturalHeight for the canvas dimensions,
    // as these reflect the true dimensions of the decoded image.
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;

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

    // If, after successful decode, dimensions are 0 (e.g. for a valid but 0x0 image file),
    // return the 0x0 canvas. Filtering is not possible or meaningful.
    if (width === 0 || height === 0) {
        console.warn("Image has zero width or height after successful load/decode. Returning empty canvas.");
        return canvas;
    }

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, width, height);

    try {
        // Get the image data from the canvas
        const imageData = ctx.getImageData(0, 0, width, height);
        const data = imageData.data; // This is a Uint8ClampedArray

        // Apply sepia filter pixel by pixel
        // Iterate over each pixel (each pixel consists of 4 values: R, G, B, A)
        for (let i = 0; i < data.length; i += 4) {
            const r = data[i];     // Red value of the current pixel
            const g = data[i+1];   // Green value
            const b = data[i+2];   // Blue value
            // Alpha value (data[i+3]) is typically left unchanged for sepia effect

            // Standard sepia calculation formula
            const tr = 0.393 * r + 0.769 * g + 0.189 * b; // New red
            const tg = 0.349 * r + 0.686 * g + 0.168 * b; // New green
            const tb = 0.272 * r + 0.534 * g + 0.131 * b; // New blue

            // Assign new values.
            // Uint8ClampedArray automatically clamps values to the 0-255 range.
            // So, Math.min(255, ...) is not strictly needed if only positive results expected,
            // but it's good practice for clarity or if intermediate results could be negative.
            // Sepia coefficients are positive, so results here will be non-negative.
            data[i] = tr;
            data[i+1] = tg;
            data[i+2] = tb;
        }

        // Put the modified image data back onto the canvas
        ctx.putImageData(imageData, 0, 0);

    } catch (e) {
        // This error can occur if the canvas is tainted (e.g., trying to get image data
        // from a canvas that has a cross-origin image drawn on it without CORS approval).
        console.error("Error applying sepia filter to canvas (e.g. CORS issue):", e);
        // In case of such an error, the canvas currently holds the original image (drawn by ctx.drawImage).
        // Returning it as is provides a graceful fallback: display the original image if the filter can't be applied.
        // The developer will see the error in the console.
    }

    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 Sepia Filter Application allows users to apply a sepia filter to their images, giving them a warm, vintage appearance. This tool can be used for enhancing photos for social media posting, creating aesthetic designs, or revitalizing old images. Users simply upload their image, and the tool processes it to add the sepia effect. It also includes error handling to inform users about any issues with loading or processing the image.

Leave a Reply

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