Please bookmark this page to avoid losing your image tool!

Video To VHSrip 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.
async function processImage(originalImg, chromaticAberration = "5", noiseLevel = "0.08", scanlineWidth = "2", showOSD = "true") {
  const canvas = document.createElement('canvas');
  const width = originalImg.width;
  const height = originalImg.height;
  canvas.width = width;
  canvas.height = height;
  const ctx = canvas.getContext('2d', { willReadFrequently: true });

  // Draw the base image
  ctx.drawImage(originalImg, 0, 0);

  // Get image data to apply VHS distortion, chromatic aberration, and noise manually
  const imgData = ctx.getImageData(0, 0, width, height);
  const data = imgData.data;
  const outData = new Uint8ClampedArray(data.length);

  const aberration = Math.round(Number(chromaticAberration) * (width / 800));
  const noise = Number(noiseLevel) * 255;
  const sWidth = Math.max(1, Math.round(Number(scanlineWidth) * (height / 800)));

  // Traverse pixels
  for (let y = 0; y < height; y++) {
    let trackingShift = 0;
    let noiseMultiplier = 1;
    
    // Bottom tracking noise zone (typical for old VHS tapes)
    if (y > height * 0.92 && y < height * 0.97) {
      trackingShift = (Math.random() - 0.5) * (width * 0.03);
      noiseMultiplier = 4;
    } 
    // Random occasional glitch lines elsewhere
    else if (Math.random() > 0.99) {
      trackingShift = (Math.random() - 0.5) * (width * 0.02);
      noiseMultiplier = 2;
    }

    // Gentle wavy distortion across the screen
    const wave = Math.sin(y / height * Math.PI * 10) * width * 0.002;
    const shiftX = trackingShift + wave;

    for (let x = 0; x < width; x++) {
      const i = (y * width + x) * 4;
      
      // Calculate shifted positions for RGB channels
      let rX = Math.round(Math.min(Math.max(x + aberration + shiftX, 0), width - 1));
      let gX = Math.round(Math.min(Math.max(x + shiftX, 0), width - 1));
      let bX = Math.round(Math.min(Math.max(x - aberration + shiftX, 0), width - 1));
      
      const rI = (y * width + rX) * 4;
      const gI = (y * width + gX) * 4;
      const bI = (y * width + bX) * 4;
      
      // Apply noise
      let n = (Math.random() - 0.5) * noise * noiseMultiplier;

      outData[i] = Math.min(Math.max(data[rI] + n, 0), 255);         // R
      outData[i + 1] = Math.min(Math.max(data[gI + 1] + n, 0), 255); // G
      outData[i + 2] = Math.min(Math.max(data[bI + 2] + n, 0), 255); // B
      outData[i + 3] = data[gI + 3];                                 // Alpha
    }
  }

  // Put the manipulated data back
  const newImgData = new ImageData(outData, width, height);
  ctx.putImageData(newImgData, 0, 0);

  // Soften and slightly offset the image to mimic VHS tape color ghosting
  ctx.globalAlpha = 0.4;
  ctx.filter = `blur(${Math.max(1, width * 0.001)}px)`;
  ctx.drawImage(canvas, width * 0.005, 0); 
  ctx.filter = 'none';
  ctx.globalAlpha = 1.0;

  // Add interlacing scanlines
  ctx.fillStyle = 'rgba(0, 0, 0, 0.15)';
  for (let y = 0; y < height; y += sWidth * 2) {
    ctx.fillRect(0, y, width, sWidth);
  }

  // Desaturate slightly to mimic old tape color fade
  ctx.fillStyle = 'rgba(128, 128, 128, 0.2)';
  ctx.globalCompositeOperation = 'saturation';
  ctx.fillRect(0, 0, width, height);

  // Edge darkening (vignette effect)
  ctx.globalCompositeOperation = 'source-over';
  const gradient = ctx.createRadialGradient(width/2, height/2, width*0.4, width/2, height/2, width*0.8);
  gradient.addColorStop(0, 'rgba(0,0,0,0)');
  gradient.addColorStop(1, 'rgba(0,0,0,0.6)');
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, width, height);

  // Overlay VCR OSD (On-Screen Display)
  if (String(showOSD).toLowerCase() === "true") {
    const fontName = 'VT323';
    if (!document.getElementById('vt323-font')) {
      const link = document.createElement('link');
      link.id = 'vt323-font';
      link.href = 'https://fonts.googleapis.com/css2?family=VT323&display=swap';
      link.rel = 'stylesheet';
      document.head.appendChild(link);
    }
    
    try {
      // Ensure Google font has time to load, fallback otherwise
      await document.fonts.load(`10px "${fontName}"`);
    } catch(e) {} 

    const fontSize = Math.max(16, Math.floor(height * 0.08));
    ctx.font = `${fontSize}px "${fontName}", 'Courier New', monospace`;
    ctx.fillStyle = "#ffffff";
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    
    // Add VHS text drop shadow for visibility
    ctx.shadowColor = "rgba(0, 0, 0, 0.8)";
    ctx.shadowOffsetX = 3;
    ctx.shadowOffsetY = 3;
    ctx.shadowBlur = 5;
    
    // Status text
    ctx.fillText("PLAY \u25BA", width * 0.05, height * 0.05); // \u25BA is a filled forward-pointing triangle
    
    // Time code
    ctx.fillText("0:00:00", width * 0.05, height * 0.88);

    // Tape speed/mode
    ctx.textAlign = "right";
    ctx.fillText("SP", width * 0.95, height * 0.88);
    
    // Current Date
    const d = new Date();
    const mm = ("0" + (d.getMonth() + 1)).slice(-2);
    const dd = ("0" + d.getDate()).slice(-2);
    const yy = String(d.getFullYear()).slice(-2);
    ctx.fillText(`${mm}.${dd}.${yy}`, width * 0.95, height * 0.05);
    
    // Reset shadow parameters completely
    ctx.shadowColor = "transparent";
  }

  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 applies a retro VHS aesthetic to your images, simulating the look of vintage analog video tapes. It can add realistic distortions such as chromatic aberration, scanlines, color ghosting, and film grain. Users can also include an authentic On-Screen Display (OSD) featuring classic VCR elements like a ‘PLAY’ indicator, timecodes, and date stamps. This is an ideal tool for content creators looking to add a nostalgic, lo-fi, or ’90s aesthetic to their digital photography and social media posts.

Leave a Reply

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