Please bookmark this page to avoid losing your image tool!

Photo To Video Trailer 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, overlayTexts = "UNFRIENDED,THE CONJURING,2027,NO ESCAPE,COMING SOON", animationLoopSeconds = 15) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    
    // Process text parameters
    let textArr = overlayTexts.split(',');
    while(textArr.length < 5) textArr.push("");
    
    let startTime = null;
    // Base timestamp set to year 2027 to match the trailer theme
    let baseTime = new Date("2027-10-31T23:58:45Z").getTime();

    function draw(time) {
        if (!startTime) startTime = time;
        let elapsed = (time - startTime) / 1000;
        let t = elapsed % animationLoopSeconds; 
        
        let w = canvas.width;
        let h = canvas.height;
        
        // Normalize time to a 15-second cinematic progression
        let nt = (t / animationLoopSeconds) * 15;
        
        let brightness = 100;
        let invert = 0;
        let glitching = false;
        let glitchAmount = 0;
        let showText = "";
        let redOverlay = 0;
        let vignette = 0.65;
        let grayscale = 40;
        let blurAmount = 0;
        
        // Timings for different trailer phases
        if (nt < 2) {
            // Fade in and first text
            brightness = 20 + (nt / 2) * 60; 
            showText = textArr[0];
            if (Math.random() > 0.95) glitching = true;
            glitchAmount = w * 0.02;
        } else if (nt < 4) {
            brightness = 60 + Math.random() * 10;
            showText = textArr[1];
            if (Math.random() > 0.8) glitching = true;
            glitchAmount = w * 0.03;
        } else if (nt < 5) {
            // Tension drop
            brightness = 25;
            showText = "";
            if (Math.random() > 0.9) glitching = true;
        } else if (nt < 7) {
            // Red tint & 2027 reveal
            brightness = 40 + Math.random() * 20;
            redOverlay = 0.3;
            showText = textArr[2];
            if (Math.random() > 0.6) glitching = true;
            glitchAmount = w * 0.05;
        } else if (nt < 9) {
            brightness = 35;
            showText = textArr[3];
            if (Math.random() > 0.8) glitching = true;
            glitchAmount = w * 0.02;
        } else if (nt < 11) {
            // Intense Jumpscare phase
            if (Math.random() > 0.5) {
                invert = 100;
                brightness = 150 + Math.random() * 50;
                glitching = true;
                glitchAmount = w * 0.1;
                grayscale = 0;
                redOverlay = 0.5;
            } else {
                invert = 0;
                brightness = 30;
                redOverlay = 0.2;
            }
        } else if (nt < 13) {
            // Final rapid flash
            brightness = 30 + Math.random() * 10;
            showText = textArr[4];
            if (Math.random() > 0.6) glitching = true;
            glitchAmount = w * 0.04;
        } else {
            // Fade out to black
            brightness = Math.max(0, 30 - ((nt - 13) / 2) * 30); 
            blurAmount = (nt - 13) * 2;
        }
        
        // Draw base image with css filters
        ctx.filter = `brightness(${brightness}%) invert(${invert}%) grayscale(${grayscale}%) blur(${blurAmount}px)`;
        ctx.drawImage(originalImg, 0, 0, w, h);
        ctx.filter = 'none';

        // Apply visual glitch distortion
        if (glitching) {
            let slices = 5 + Math.random() * 10;
            for(let i = 0; i < slices; i++) {
                let sy = Math.random() * h;
                let sh = Math.random() * (h / 10);
                let dx = (Math.random() - 0.5) * glitchAmount;
                ctx.drawImage(canvas, 0, sy, w, sh, dx, sy, w, sh); 
            }
        }

        // Apply dark red tint
        if (redOverlay > 0) {
            ctx.fillStyle = `rgba(200, 0, 0, ${redOverlay})`;
            ctx.fillRect(0, 0, w, h);
        }

        // Apply Vignette for scary mood
        let gradient = ctx.createRadialGradient(w/2, h/2, Math.min(w,h) * 0.2, w/2, h/2, Math.max(w,h) * 0.8);
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        gradient.addColorStop(1, `rgba(0,0,0,${vignette})`);
        ctx.fillStyle = gradient;
        ctx.fillRect(0,0,w,h);

        // Render CRT interlaced scanlines
        let scanlineWidth = Math.max(1, Math.floor(h / 300));
        ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
        for (let y = 0; y < h; y += scanlineWidth * 2) {
            ctx.fillRect(0, y, w, scanlineWidth);
        }

        // Render "Unfriended" style Camcorder UI
        let recBlink = (Math.floor(time / 500) % 2 === 0);
        let fontSize = Math.max(14, h * 0.04);
        ctx.font = `bold ${fontSize}px "Courier New", Courier, monospace`;
        ctx.textAlign = 'left';
        ctx.textBaseline = 'middle';
        
        let pad = Math.max(10, h * 0.05);
        
        // REC indicator
        if (recBlink) {
            ctx.fillStyle = '#ff0000';
            ctx.beginPath();
            ctx.arc(pad + fontSize*0.5, pad, fontSize*0.4, 0, Math.PI*2);
            ctx.fill();
        }
        ctx.fillStyle = '#ffffff';
        ctx.fillText("REC", pad + fontSize*1.2, pad);
        
        // Timestamp
        let dt = new Date(baseTime + elapsed * 1000);
        let timeStr = dt.toISOString().substring(11, 19);
        ctx.textAlign = 'right';
        ctx.fillText(timeStr, w - pad, pad);
        
        // Low Battery Icon
        ctx.strokeStyle = '#ffffff';
        ctx.lineWidth = Math.max(1, fontSize * 0.1);
        let bw = fontSize * 2;
        let bh = fontSize;
        let bx = w - pad - bw;
        let by = h - pad - bh;
        ctx.strokeRect(bx, by, bw, bh);
        ctx.fillRect(bx + bw, by + bh*0.25, bw*0.1, bh*0.5); // battery tip
        
        // Make battery blink red when recording dot blinks
        ctx.fillStyle = recBlink ? '#ff0000' : '#ffffff';
        ctx.fillRect(bx + bw*0.1, by + bh*0.1, bw*0.2, bh*0.8);

        // Render Cinematic Trailer Text
        if (showText && showText.trim() !== "") {
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            let titleSize = Math.max(30, h*0.12);
            ctx.font = `400 ${titleSize}px Impact, sans-serif`;
            
            let tx = w/2;
            let ty = h/2;
            if (glitching) {
                // Jitter
                tx += (Math.random() - 0.5) * (w*0.03);
                ty += (Math.random() - 0.5) * (h*0.03);
                ctx.fillStyle = (Math.random() > 0.5) ? '#ff0000' : '#ffffff';
            } else {
                ctx.fillStyle = '#ffffff';
            }
            
            ctx.lineWidth = Math.max(1, titleSize*0.02);
            ctx.strokeStyle = '#000000';
            ctx.shadowColor = '#000000';
            ctx.shadowBlur = 15;
            ctx.strokeText(showText, tx, ty);
            ctx.fillText(showText, tx, ty);
            ctx.shadowBlur = 0; // reset
        }

        // Add TV Grain / Static noise
        ctx.fillStyle = 'rgba(255,255,255,0.07)';
        let noiseCount = Math.floor(w * h * 0.0002);
        for(let i = 0; i < noiseCount; i++) {
            let nx = Math.random() * w;
            let ny = Math.random() * h;
            let ns = Math.random() * 3 + 1;
            ctx.fillRect(nx, ny, ns, ns);
        }

        requestAnimationFrame(draw);
    }
    
    // Start animation loop
    requestAnimationFrame(draw);
    
    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

This tool transforms a single static image into a cinematic, horror-themed video trailer. It applies a sequence of dynamic visual effects including glitch distortions, brightness fluctuations, red color overlays, and vignette shading to create tension. The tool also overlays customizable text, a camcorder-style user interface (such as ‘REC’ indicators, timestamps, and battery icons), and CRT scanline effects to simulate a found-footage or analog horror aesthetic. It is ideal for content creators looking to make dramatic teasers, social media promos, or stylized visual effects for horror-themed projects.

Leave a Reply

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