Please bookmark this page to avoid losing your image tool!

Dual Effect Image Creator

(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,
    color1 = "#ff0055",
    color2 = "#00ccff",
    orientation = "horizontal",
    blendMode = "color",
    intensity = 0.8,
    lightSpread = 0.8,
    vignetteStrength = 0.5
) {
    // Set up canvas and context
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    const w = originalImg.width;
    const h = originalImg.height;
    
    canvas.width = w;
    canvas.height = h;

    // 1. Draw the original image naturally
    ctx.drawImage(originalImg, 0, 0, w, h);

    // 2. Add Vignette (darken the edges) to make lighting pop more realistically
    if (vignetteStrength > 0) {
        const cx = w / 2;
        const cy = h / 2;
        // Radius safely reaches the corners
        const radius = Math.hypot(w / 2, h / 2);
        const vigGrad = ctx.createRadialGradient(cx, cy, radius * 0.3, cx, cy, radius);
        
        // Fading from transparent black to semi-transparent black prevents gray-mud in some browsers
        vigGrad.addColorStop(0, "rgba(0, 0, 0, 0)");
        vigGrad.addColorStop(1, `rgba(0, 0, 0, ${Math.min(1, vignetteStrength)})`);
        
        ctx.globalCompositeOperation = "multiply";
        ctx.fillStyle = vigGrad;
        ctx.fillRect(0, 0, w, h);
    }

    // A helper to safely parse any valid CSS color into RGB components
    function parseColor(colorStr) {
        const tempCanvas = document.createElement("canvas");
        tempCanvas.width = 1;
        tempCanvas.height = 1;
        const tempCtx = tempCanvas.getContext("2d", { willReadFrequently: true });
        tempCtx.fillStyle = colorStr;
        tempCtx.fillRect(0, 0, 1, 1);
        const data = tempCtx.getImageData(0, 0, 1, 1).data;
        return { r: data[0], g: data[1], b: data[2] };
    }

    const c1 = parseColor(color1);
    const c2 = parseColor(color2);

    // Clamp spread parameter
    const spread = Math.max(0.01, Math.min(1.0, lightSpread));
    const safeIntensity = Math.max(0, Math.min(1.0, intensity));

    // Calculate light gradient coordinates based on orientation
    let x1_start = 0, y1_start = 0, x1_end = 0, y1_end = 0;
    let x2_start = 0, y2_start = 0, x2_end = 0, y2_end = 0;

    if (orientation === "vertical") {
        // Top to Bottom
        x1_start = 0; y1_start = 0;
        x1_end = 0; y1_end = h * spread;

        // Bottom to Top
        x2_start = 0; y2_start = h;
        x2_end = 0; y2_end = h - (h * spread);
    } else if (orientation === "diagonal") {
        // Top-Left to Center
        x1_start = 0; y1_start = 0;
        x1_end = w * spread; y1_end = h * spread;

        // Bottom-Right to Center 
        x2_start = w; y2_start = h;
        x2_end = w - (w * spread); y2_end = h - (h * spread);
    } else {
        // horizontal fallback (Left and Right)
        x1_start = 0; y1_start = 0;
        x1_end = w * spread; y1_end = 0;

        x2_start = w; y2_start = 0;
        x2_end = w - (w * spread); y2_end = 0;
    }

    // Apply valid blend mode fallback
    const validModes = [
        "source-over", "multiply", "screen", "overlay", "darken", "lighten", 
        "color-dodge", "color-burn", "hard-light", "soft-light", "difference", 
        "exclusion", "hue", "saturation", "color", "luminosity"
    ];
    ctx.globalCompositeOperation = validModes.includes(blendMode) ? blendMode : "color";

    // 3. Draw Light 1 (Color 1)
    const grad1 = ctx.createLinearGradient(x1_start, y1_start, x1_end, y1_end);
    grad1.addColorStop(0, `rgba(${c1.r}, ${c1.g}, ${c1.b}, ${safeIntensity})`);
    grad1.addColorStop(1, `rgba(${c1.r}, ${c1.g}, ${c1.b}, 0)`); // Same RGB to prevent muddy interpolation 
    ctx.fillStyle = grad1;
    ctx.fillRect(0, 0, w, h);

    // 4. Draw Light 2 (Color 2)
    const grad2 = ctx.createLinearGradient(x2_start, y2_start, x2_end, y2_end);
    grad2.addColorStop(0, `rgba(${c2.r}, ${c2.g}, ${c2.b}, ${safeIntensity})`);
    grad2.addColorStop(1, `rgba(${c2.r}, ${c2.g}, ${c2.b}, 0)`);
    ctx.fillStyle = grad2;
    ctx.fillRect(0, 0, w, h);

    // Reset composite operation to default
    ctx.globalCompositeOperation = "source-over";

    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 Dual Effect Image Creator is an image editing tool that applies cinematic lighting effects to your photos using dual-color gradients. Users can customize the orientation of the light (horizontal, vertical, or diagonal), choose two specific colors, and adjust settings like intensity, light spread, and vignette strength to create depth. This tool is ideal for graphic designers, social media creators, and photographers looking to add artistic atmosphere, stylized color grading, or dramatic lighting to portraits and digital artwork.

Leave a Reply

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