Please bookmark this page to avoid losing your image tool!

Image Daguerreotype Filter

(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, contrast = 50, blueBoost = 30, greenBoost = 10, vignetteStrength = 0.7, vignetteStart = 0.3) {
    // Ensure image is loaded and valid
    if (!originalImg || typeof originalImg.naturalWidth === 'undefined' || !originalImg.complete || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
        console.error("Image not loaded or invalid. Cannot process.");
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = 200; 
        errorCanvas.height = 50;
        const errorCtx = errorCanvas.getContext('2d');
        if (errorCtx) {
            errorCtx.fillStyle = '#fdd'; // Light red background
            errorCtx.fillRect(0,0,errorCanvas.width,errorCanvas.height);
            errorCtx.font = "bold 14px Arial"; 
            errorCtx.fillStyle = "#D8000C"; // Dark red text
            errorCtx.textAlign = "center";
            errorCtx.textBaseline = "middle";
            errorCtx.fillText("Error: Invalid Image", errorCanvas.width/2, errorCanvas.height/2);
        }
        return errorCanvas;
    }

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

    // Check if context was successfully created
    if (!ctx) {
        console.error("Canvas 2D context is not supported.");
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = 200; 
        errorCanvas.height = 50;
        const errorCtxFallback = errorCanvas.getContext('2d');
        if (errorCtxFallback) {
            errorCtxFallback.fillStyle = '#fdd';
            errorCtxFallback.fillRect(0,0,errorCanvas.width,errorCanvas.height);
            errorCtxFallback.font = "bold 14px Arial"; 
            errorCtxFallback.fillStyle = "#D8000C";
            errorCtxFallback.textAlign = "center";
            errorCtxFallback.textBaseline = "middle";
            errorCtxFallback.fillText("Error: Canvas Not Supported", errorCanvas.width/2, errorCanvas.height/2);
        }
        return errorCanvas;
    }

    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

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

    // Get image data for pixel manipulation
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This can happen due to tainted canvas (CORS issues with image source)
        console.error("Could not getImageData (e.g., CORS issue): ", e.message);
        // Return canvas with original image drawn, and add a warning message
        ctx.font = "bold 16px Arial";
        ctx.fillStyle = "rgba(216, 0, 12, 0.8)"; // Dark red, semi-transparent
        ctx.textAlign = "center";
        ctx.textBaseline = "top";
        // Simple drop shadow for text readability
        ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
        ctx.fillText("Original shown. Processing failed (CORS issue?).", canvas.width / 2 + 1, 20 + 1);
        ctx.fillStyle = "rgba(255, 200, 200, 0.9)";
        ctx.fillText("Original shown. Processing failed (CORS issue?).", canvas.width / 2, 20);
        return canvas; 
    }
    
    const data = imageData.data;
    const width = canvas.width;
    const height = canvas.height;

    // --- Pixel manipulation: Grayscale, Tint, Contrast ---

    // Clamp contrast parameter. The contrast formula is sensitive.
    // C needs to be in range like (-259, 259). We use a slightly tighter range for C.
    let C = Math.max(-255, Math.min(255, contrast)); 
    if (C === 259 || C === -259) C = 258 * Math.sign(C); // Ensure no division by zero in extreme case

    const contrastFactor = (259 * (C + 255)) / (255 * (259 - C));

    for (let i = 0; i < data.length; i += 4) {
        let rInitial = data[i];
        let gInitial = data[i+1];
        let bInitial = data[i+2];

        // Convert to grayscale
        let gray = 0.299 * rInitial + 0.587 * gInitial + 0.114 * bInitial;

        // Apply Daguerreotype tint (typically cool, slightly blue/green)
        // Tinting is done on the grayscale value.
        let tintedR = gray; 
        let tintedG = gray + greenBoost;
        let tintedB = gray + blueBoost;
        
        // Clamp initial tinted values to [0, 255] before applying contrast
        tintedR = Math.max(0, Math.min(255, tintedR));
        tintedG = Math.max(0, Math.min(255, tintedG));
        tintedB = Math.max(0, Math.min(255, tintedB));
        
        // Apply contrast to the tinted grayscale values
        let r = contrastFactor * (tintedR - 128) + 128;
        let g = contrastFactor * (tintedG - 128) + 128;
        let b = contrastFactor * (tintedB - 128) + 128;

        // Clamp final RGB values to [0, 255]
        data[i] = Math.max(0, Math.min(255, r));
        data[i+1] = Math.max(0, Math.min(255, g));
        data[i+2] = Math.max(0, Math.min(255, b));
        // Alpha channel (data[i+3]) is preserved
    }
    ctx.putImageData(imageData, 0, 0);

    // --- Vignette Pass ---
    const centerX = width / 2;
    const centerY = height / 2;
    
    // Calculate the furthest distance from center to a corner for outer radius
    const outerRadius = Math.sqrt(Math.pow(centerX, 2) + Math.pow(centerY, 2));
    
    // vignetteStart (0-1) determines the relative size of the transparent inner circle.
    // Clamp vignetteStart to [0, 1] to prevent invalid gradient radiuses.
    const clampedVignetteStart = Math.max(0, Math.min(1, vignetteStart));
    const innerRadius = outerRadius * clampedVignetteStart; 

    // Clamp vignetteStrength (opacity) to [0, 1]
    const clampedVignetteStrength = Math.max(0, Math.min(1, vignetteStrength));

    // Create a radial gradient for the vignette effect
    const gradient = ctx.createRadialGradient(centerX, centerY, innerRadius, centerX, centerY, outerRadius);
    gradient.addColorStop(0, 'rgba(0,0,0,0)'); // Center of gradient (at innerRadius distance) is transparent
    gradient.addColorStop(1, `rgba(0,0,0,${clampedVignetteStrength})`); // Edge of gradient (at outerRadius distance) is dark

    // Apply the vignette gradient as an overlay
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);

    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 Daguerreotype Filter is a tool designed to apply a classic photographic effect to images, reminiscent of the 19th-century daguerreotype process. This tool allows users to enhance their images by adjusting various parameters including contrast, color tinting (blue and green boosts), and vignette strength. The result is a visually striking image with a vintage look, making it ideal for artists, photographers, and anyone looking to add a unique, historical aesthetic to their digital photos. It can be useful for enhancing personal photography, creating stylized images for social media, or adding a retro vibe to digital artwork.

Leave a Reply

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