Please bookmark this page to avoid losing your image tool!

Photo Romantic 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, intensity = 0.7) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

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

    if (width === 0 || height === 0) {
        // Handle cases where the image might not be loaded or has no dimensions
        canvas.width = 0;
        canvas.height = 0;
        console.warn("Image has zero dimensions. Returning empty canvas.");
        return canvas;
    }

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

    // Clamp intensity to a practical range, e.g., [0, 1]
    // 0 means minimal/no effect, 1 means full standard effect.
    const currentIntensity = Math.max(0, Math.min(1.0, intensity));

    // --- Define effect strengths based on intensity ---

    // 1. Blur: A subtle blur for a soft, dreamy look.
    // Max blur amount at full intensity.
    const baseBlurPx = 1.5; // e.g., 1.5px blur at intensity = 1
    const blurPx = baseBlurPx * currentIntensity;

    // 2. Brightness & Contrast: Minor adjustments for a slightly more vivid image.
    const baseBrightness = 1.05; // Target 105% brightness at intensity = 1
    const brightnessEffect = 1 + (baseBrightness - 1) * currentIntensity;

    const baseContrast = 1.05; // Target 105% contrast at intensity = 1
    const contrastEffect = 1 + (baseContrast - 1) * currentIntensity;
    
    // 3. Color Tint: Adjust pixel colors for a warm, pinkish/magenta "romantic" hue.
    // These are amounts to add/subtract from R,G,B channels.
    const basePinkBoost = 20;     // Boosts Red and Blue, mildly reduces Green for pinkness.
    const baseWarmthBoost = 15;   // Additional Red boost for overall warmth.
    
    const pinkBoost = basePinkBoost * currentIntensity;
    const warmthBoost = baseWarmthBoost * currentIntensity;

    // 4. Vignette: Darken image corners to draw focus to the center.
    const baseVignetteAlpha = 0.6; // Max opacity of the vignette color at edges.
    const vignetteAlpha = baseVignetteAlpha * currentIntensity;
    // A dark, warm magenta for the vignette color.
    const vignetteOuterColor = `rgba(60, 10, 30, ${vignetteAlpha.toFixed(2)})`; 
    const vignetteInnerColor = 'rgba(0, 0, 0, 0)'; // Fully transparent at the center.


    // --- Apply effects ---

    // Step 1: Draw the original image with initial filters (blur, brightness, contrast).
    // These filters are applied using the canvas context's filter property.
    let filterParts = [];
    if (blurPx > 0.05) { // Apply blur only if visually significant.
        filterParts.push(`blur(${blurPx.toFixed(2)}px)`);
    }
    if (Math.abs(brightnessEffect - 1) > 0.01) { // Apply brightness if changed meaningfully.
        filterParts.push(`brightness(${brightnessEffect.toFixed(2)})`);
    }
    if (Math.abs(contrastEffect - 1) > 0.01) { // Apply contrast if changed meaningfully.
        filterParts.push(`contrast(${contrastEffect.toFixed(2)})`);
    }

    if (filterParts.length > 0) {
        ctx.filter = filterParts.join(' ');
    } else {
        ctx.filter = 'none'; // No filter if effects are negligible.
    }
    
    ctx.drawImage(originalImg, 0, 0, width, height);
    ctx.filter = 'none'; // Reset filter for any subsequent canvas drawing (like vignette).

    // Optimization: If intensity is very low, the visual changes from pixel manipulation
    // and vignette might be unnoticeable. Skip them to save processing.
    if (currentIntensity < 0.01) {
        return canvas; // Canvas contains the image with initial (minor) filters applied.
    }

    // Step 2: Get image data for pixel-level manipulation (color tinting).
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, width, height);
    } catch (e) {
        // This error can occur if the image is loaded from a cross-origin source
        // without proper CORS headers, tainting the canvas.
        console.error("Error getting imageData. Ensure the image is CORS-compatible or from the same origin.", e);
        // Fallback: Return the canvas with only the context filters applied.
        return canvas; 
    }
    const data = imageData.data; // data is a Uint8ClampedArray: [R,G,B,A, R,G,B,A, ...]

    // Step 3: Apply color tint pixel by pixel.
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];

        // Apply calculated warmth and pinkish hue.
        r += warmthBoost + pinkBoost;       // Boost Red for warmth and pinkness.
        g -= pinkBoost / 1.5;              // Reduce Green for a stronger pink/magenta effect.
        b += pinkBoost;                    // Boost Blue for pinkness.

        // Ensure values are rounded and clamped to the valid [0, 255] range.
        data[i]     = Math.max(0, Math.min(255, Math.round(r)));
        data[i + 1] = Math.max(0, Math.min(255, Math.round(g)));
        data[i + 2] = Math.max(0, Math.min(255, Math.round(b)));
        // Alpha channel (data[i+3]) remains unchanged.
    }

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

    // Step 5: Apply vignette effect over the image.
    // The vignette is drawn as a radial gradient.
    if (vignetteAlpha > 0.01) { // Apply vignette only if its opacity is significant.
        const centerX = width / 2;
        const centerY = height / 2;

        // Define the vignette's geometry.
        const endRadius = Math.sqrt(centerX * centerX + centerY * centerY); // Max radius to image corners.
        const startRadiusRatio = 0.15; // Size of the fully transparent central area relative to endRadius.
        
        const fadeStartRadius = endRadius * startRadiusRatio; 
        const fadeEndRadius = endRadius * 0.90; // Vignette reaches full color near the edges.

        const gradient = ctx.createRadialGradient(
            centerX, centerY, fadeStartRadius,
            centerX, centerY, fadeEndRadius
        );

        // Configure gradient color stops.
        gradient.addColorStop(0, vignetteInnerColor); // Center: transparent.
        gradient.addColorStop(1, vignetteOuterColor); // Edges: dark, semi-transparent color.

        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, width, height); // Draw the gradient over the entire canvas.
    }

    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 Photo Romantic Filter Application is a tool designed to enhance your images with a romantic aesthetic. By applying soft blur effects, brightness and contrast adjustments, warm color tints, and vignette effects, this tool transforms ordinary photos into visually appealing artworks that are perfect for sharing on social media, creating romantic gifts, or simply enhancing personal photo collections. From softening the overall look to adding a pinkish hue, this application helps you achieve a dreamy effect that can elevate the emotional impact of your images.

Leave a Reply

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