Please bookmark this page to avoid losing your image tool!

Video Platform Screenshot And Rip Effect Converter

(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, 
    subtitleText = "I'VE BEEN WAITING FOR THIS MOMENT.", 
    videoTitle = "VHS_RIP_HIFI_MONO_DUB.avi", 
    timeCode = "00:24:12 / 01:45:00", 
    glitchIntensity = 10, 
    noiseLevel = 25
) {
    // Ensure numeric values
    glitchIntensity = Number(glitchIntensity) || 10;
    noiseLevel = Number(noiseLevel) || 25;

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

    // 1. Draw base image with slight blur & contrast adjustment for the VHS/DVDRip feel
    ctx.filter = 'contrast(1.2) saturate(0.85) blur(0.6px)';
    ctx.drawImage(originalImg, 0, 0);
    ctx.filter = 'none';

    // Scale multiplier for relative UI sizing
    const scale = Math.max(1, canvas.width / 800);

    // 2. Apply Chromatic Aberration and Grain Noise
    if (glitchIntensity > 0 || noiseLevel > 0) {
        const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imgData.data;
        const outData = new Uint8ClampedArray(data);
        
        // Pixel drift amount
        const shiftR = Math.floor(canvas.width * (glitchIntensity / 2000));
        const shiftB = -Math.floor(canvas.width * (glitchIntensity / 2000));

        for (let y = 0; y < canvas.height; y++) {
            for (let x = 0; x < canvas.width; x++) {
                const i = (y * canvas.width + x) * 4;
                
                // Random TV static/noise
                const noise = (Math.random() - 0.5) * noiseLevel;

                const rx = Math.max(0, Math.min(canvas.width - 1, x - shiftR));
                const bx = Math.max(0, Math.min(canvas.width - 1, x - shiftB));
                
                const iR = (y * canvas.width + rx) * 4;
                const iB = (y * canvas.width + bx) * 4;

                outData[i] = Math.min(255, Math.max(0, data[iR] + noise));         // Red Channel Shift + Noise
                outData[i+1] = Math.min(255, Math.max(0, data[i+1] + noise));      // Green Channel Base + Noise
                outData[i+2] = Math.min(255, Math.max(0, data[iB+2] + noise));     // Blue Channel Shift + Noise
                outData[i+3] = data[i+3];                                          // Alpha Channel
            }
        }
        ctx.putImageData(new ImageData(outData, canvas.width, canvas.height), 0, 0);
    }

    // 3. VHS Scanlines
    ctx.fillStyle = 'rgba(0, 0, 0, 0.15)';
    for (let y = 0; y < canvas.height; y += 4) {
        ctx.fillRect(0, y, canvas.width, 1.5);
    }
    ctx.fillStyle = 'rgba(255, 255, 255, 0.05)';
    for (let y = 2; y < canvas.height; y += 4) {
        ctx.fillRect(0, y, canvas.width, 1);
    }

    // 4. Horizontal Glitch Tears (Tracking error)
    const numTears = Math.floor(Math.random() * glitchIntensity);
    for (let j = 0; j < numTears; j++) {
        const tearY = Math.random() * canvas.height;
        const tearH = Math.random() * 15 * scale;
        const tearX = (Math.random() - 0.5) * glitchIntensity * 6 * scale;
        ctx.drawImage(canvas, 0, tearY, canvas.width, tearH, tearX, tearY, canvas.width, tearH);
    }

    // 5. Video Player Platform Overlay (Screenshot interface look)
    const barHeight = 45 * scale;
    
    // Bottom vignette to make subs / player legible
    const grad = ctx.createLinearGradient(0, canvas.height - barHeight - 90 * scale, 0, canvas.height);
    grad.addColorStop(0, 'rgba(0,0,0,0)');
    grad.addColorStop(1, 'rgba(0,0,0,0.85)');
    ctx.fillStyle = grad;
    ctx.fillRect(0, canvas.height - barHeight - 90 * scale, canvas.width, barHeight + 90 * scale);

    // Player bottom bar
    ctx.fillStyle = 'rgba(15, 15, 15, 0.9)';
    ctx.fillRect(0, canvas.height - barHeight, canvas.width, barHeight);

    // Progress bar timeline
    ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
    ctx.fillRect(0, canvas.height - barHeight, canvas.width, 4 * scale);
    ctx.fillStyle = '#ff0000'; // Active tracking playback
    const progress = 0.35 + Math.random() * 0.4; // random position between 35% - 75%
    ctx.fillRect(0, canvas.height - barHeight, canvas.width * progress, 4 * scale);
    ctx.beginPath();
    ctx.arc(canvas.width * progress, canvas.height - barHeight + 2 * scale, 6 * scale, 0, Math.PI * 2);
    ctx.fill();

    // Player Toolbar Icons Let side (Play, skip, volume)
    ctx.fillStyle = '#FFFFFF';
    ctx.font = `${18 * scale}px Arial`;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillText("▶", 20 * scale, canvas.height - barHeight / 2);
    ctx.font = `${16 * scale}px Arial`;
    ctx.fillText("⏭", 55 * scale, canvas.height - barHeight / 2);
    ctx.fillText("🔊", 95 * scale, canvas.height - barHeight / 2);

    // Timecode
    ctx.font = `${14 * scale}px "Lucida Console", Monaco, monospace`;
    ctx.fillText(timeCode, 130 * scale, canvas.height - barHeight / 2 + 1 * scale);

    // Player Toolbar Icons Right side (Settings, Fullscreen)
    ctx.textAlign = 'right';
    ctx.fillText("⚙", canvas.width - 60 * scale, canvas.height - barHeight / 2);
    ctx.font = `${16 * scale}px Arial`;
    ctx.fillText("⛶", canvas.width - 25 * scale, canvas.height - barHeight / 2);

    // VCR / Player OSD at the top-left (Retro UI style)
    ctx.font = `bold ${24 * scale}px "Courier New", Courier, monospace`;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'top';
    ctx.fillStyle = '#00FF00'; // Retro VCR green
    ctx.shadowOffsetX = 2 * scale;
    ctx.shadowOffsetY = 2 * scale;
    ctx.shadowColor = 'rgba(0,0,0,1)';
    ctx.shadowBlur = 4 * scale;
    ctx.fillText("PLAY ►", 25 * scale, 25 * scale);
    
    ctx.font = `${16 * scale}px "Courier New", Courier, monospace`;
    ctx.fillStyle = '#FFFFFF'; // Info text
    ctx.fillText(`FILE: ${videoTitle}`, 25 * scale, 55 * scale);
    
    // Reset shadow
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;
    ctx.shadowBlur = 0;

    // 6. Mono Language Dub Translator Text (Stylized DVDRip subtitles)
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    
    ctx.font = `bold ${36 * scale}px Arial, Helvetica, sans-serif`;
    ctx.lineWidth = 5 * scale;
    ctx.strokeStyle = '#000000';
    ctx.fillStyle = '#FFDD00'; // High-contrast rip yellow
    
    // Support multi-line subtitles separated by actual newline or \n strings
    const lines = String(subtitleText).replace(/\\n/g, '\n').split('\n');
    let currentY = canvas.height - barHeight - 25 * scale - (lines.length - 1) * (40 * scale);
    
    lines.forEach(line => {
        // Render outline
        ctx.lineJoin = 'round';
        ctx.miterLimit = 2;
        ctx.strokeText(line, canvas.width / 2, currentY);
        // Render inside text
        ctx.fillText(line, canvas.width / 2, currentY);
        currentY += 40 * scale;
    });

    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 standard images into stylized screenshots that mimic the aesthetic of vintage video media, such as VHS tapes or DVD rips. It applies retro visual effects including chromatic aberration, film grain, scanlines, and horizontal tracking errors to create a nostalgic, lo-fi look. Additionally, the tool overlays a simulated video player interface, complete with a playback progress bar, timecodes, control icons, and customizable subtitles. It is ideal for creators looking to produce retro-themed social media content, aesthetic meme art, or vintage-style cinematic visuals.

Leave a Reply

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