Please bookmark this page to avoid losing your image tool!

Image Timestamp Based On Metadata Adder

(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, format = 'YYYY-MM-DD HH:mm:ss', position = 'bottom-right', fontSize = 24, fontColor = 'white', fontFamily = 'Arial', backgroundColor = 'rgba(0, 0, 0, 0.5)', padding = 10) {

    /**
     * Formats a Date object into a specified string format.
     * @param {Date} date The date to format.
     * @param {string} fmt The format string (e.g., 'YYYY-MM-DD HH:mm:ss').
     * @returns {string} The formatted date string.
     */
    const formatDate = (date, fmt) => {
        const pad = (num) => num.toString().padStart(2, '0');
        const replacements = {
            'YYYY': date.getFullYear(),
            'MM': pad(date.getMonth() + 1),
            'DD': pad(date.getDate()),
            'HH': pad(date.getHours()),
            'mm': pad(date.getMinutes()),
            'ss': pad(date.getSeconds())
        };
        let formattedString = fmt;
        for (const key in replacements) {
            formattedString = formattedString.replace(new RegExp(key, 'g'), replacements[key]);
        }
        return formattedString;
    };

    let timestampDate;

    try {
        // Step 1: Dynamically import the exifreader library.
        const ExifReader = (await import('https://cdn.jsdelivr.net/npm/exifreader@4.21.0/dist/exifreader.mjs')).default;

        // Step 2: Fetch the image data from its source to get the raw bytes.
        // This is necessary because the Image object itself doesn't hold the metadata.
        const response = await fetch(originalImg.src);
        if (!response.ok) {
            throw new Error(`Failed to fetch image data. Status: ${response.status}`);
        }
        const arrayBuffer = await response.arrayBuffer();

        // Step 3: Parse EXIF data from the image's array buffer.
        const tags = ExifReader.load(arrayBuffer);
        const dateTimeOriginal = tags['DateTimeOriginal']?.description; // e.g., "2023:09:21 14:30:00"

        if (dateTimeOriginal) {
            // EXIF date format is 'YYYY:MM:DD HH:MM:SS'. Convert it to a format
            // that the Date constructor can reliably parse (ISO 8601-like).
            const [datePart, timePart] = dateTimeOriginal.split(' ');
            if (datePart && timePart) {
                const isoDateTime = `${datePart.replace(/:/g, '-')}T${timePart}`;
                const parsedDate = new Date(isoDateTime);
                // Check if the parsed date is valid.
                if (!isNaN(parsedDate.getTime())) {
                    timestampDate = parsedDate;
                } else {
                    console.warn(`Invalid date format in EXIF tag: ${dateTimeOriginal}. Using current date.`);
                    timestampDate = new Date();
                }
            } else {
                console.warn(`Could not parse EXIF DateTime: ${dateTimeOriginal}. Using current date.`);
                timestampDate = new Date();
            }
        } else {
            // Fallback if the 'DateTimeOriginal' EXIF tag is not found.
            console.warn("No 'DateTimeOriginal' EXIF tag found. Using current date and time.");
            timestampDate = new Date();
        }
    } catch (error) {
        console.error("Could not read EXIF data:", error);
        // Fallback if fetching the image, loading the library, or parsing fails.
        timestampDate = new Date();
    }

    // Step 4: Create the final formatted date string for display.
    const formattedDate = formatDate(timestampDate, format);

    // Step 5: Create a canvas to draw the image and the timestamp.
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    const ctx = canvas.getContext('2d');
    
    // Draw the original image onto the canvas.
    ctx.drawImage(originalImg, 0, 0);

    // Step 6: Configure canvas context for drawing the text.
    ctx.font = `${fontSize}px ${fontFamily}`;
    
    // Step 7: Calculate dimensions and position for the timestamp and its background.
    const metrics = ctx.measureText(formattedDate);
    const textWidth = metrics.width;
    const boxWidth = textWidth + (padding * 2);
    const boxHeight = fontSize + (padding * 2);

    let boxX, boxY;
    const margin = padding;

    switch (position) {
        case 'top-left':
            boxX = margin;
            boxY = margin;
            break;
        case 'top-right':
            boxX = canvas.width - boxWidth - margin;
            boxY = margin;
            break;
        case 'bottom-left':
            boxX = margin;
            boxY = canvas.height - boxHeight - margin;
            break;
        case 'center':
            boxX = (canvas.width - boxWidth) / 2;
            boxY = (canvas.height - boxHeight) / 2;
            break;
        case 'bottom-right':
        default:
            boxX = canvas.width - boxWidth - margin;
            boxY = canvas.height - boxHeight - margin;
            break;
    }

    // Step 8: Draw the semi-transparent background for better text readability.
    if (backgroundColor && backgroundColor !== 'transparent') {
        ctx.fillStyle = backgroundColor;
        ctx.fillRect(Math.round(boxX), Math.round(boxY), Math.round(boxWidth), Math.round(boxHeight));
    }
    
    // Step 9: Draw the timestamp text on top of the background.
    ctx.fillStyle = fontColor;
    ctx.textBaseline = 'middle'; // Center text vertically inside the box.
    const textX = boxX + padding;
    const textY = boxY + boxHeight / 2;
    ctx.fillText(formattedDate, Math.round(textX), Math.round(textY));
    
    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 Timestamp Based On Metadata Adder tool allows you to add a timestamp to your images based on the metadata embedded in the file. It extracts the original date and time the photo was taken from the EXIF data, formats it according to your specifications, and overlays it onto the image. You can customize the position, font size, color, and background style of the timestamp. This tool is useful for photographers looking to preserve the original capture time, for social media posts, or for personalizing images for presentations and memories.

Leave a Reply

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