Please bookmark this page to avoid losing your image tool!

Photo To HIFI VHSRip 16mm Effects 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, intensity = 50, colorShiftAmount = 3, noiseAmount = 25, enableText = 1) {
    const canvas = document.createElement('canvas');
    const width = originalImg.width;
    const height = originalImg.height;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

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

    // Grab pixel data for manipulation
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;
    const outData = new Uint8ClampedArray(data);

    // Calculate dynamic effect scales based on image size
    const shift = Math.max(1, Math.floor((width / 1000) * colorShiftAmount * (intensity / 50)));
    
    // Contrast adjustment factor (adds that crunchy VHS look)
    const contrast = 20 * (intensity / 50);
    const contrastFactor = (259 * (contrast + 255)) / (255 * (259 - contrast));

    // Pixel processing loop
    for (let y = 0; y < height; y++) {
        let jitter = 0;
        
        // Define bottom tracking line error (VHS characteristic)
        const isTrackingBand = (y > height * 0.90 && y < height * 0.95);

        // Apply horizontal jitter
        if (isTrackingBand) {
            jitter = Math.floor((Math.random() - 0.5) * (width / 50) * (intensity / 50));
        } else if (Math.random() < 0.03) {
            // Random jitter for standard scanlines
            jitter = Math.floor((Math.random() - 0.5) * (width / 200) * (intensity / 50));
        }

        for (let x = 0; x < width; x++) {
            const i = (y * width + x) * 4;

            // Chromatic aberration / Red-Blue shift
            let rX = Math.max(0, Math.min(width - 1, x - shift + jitter));
            let gX = Math.max(0, Math.min(width - 1, x + jitter));
            let bX = Math.max(0, Math.min(width - 1, x + shift + jitter));

            const iR = (y * width + rX) * 4;
            const iG = (y * width + gX) * 4;
            const iB = (y * width + bX) * 4;

            let r = data[iR];
            let g = data[iG + 1];
            let b = data[iB + 2];

            // Specific VHS Tracking static (speckles)
            if (isTrackingBand && Math.random() < 0.15) {
                r = g = b = 180 + Math.random() * 75;
            }

            // Apply contrast
            r = contrastFactor * (r - 128) + 128;
            g = contrastFactor * (g - 128) + 128;
            b = contrastFactor * (b - 128) + 128;

            // 16mm Color Grading (Slight warmth + green shadows typically seen in analog transfers)
            r += 10;
            g += 2;
            b -= 5;

            // Apply Film Grain / Noise
            const noise = (Math.random() - 0.5) * (noiseAmount * 2) * (intensity / 50);

            outData[i] = r + noise;
            outData[i + 1] = g + noise;
            outData[i + 2] = b + noise;
            outData[i + 3] = 255; // Alpha
        }
    }

    // Write processed pixels back
    imageData.data.set(outData);
    ctx.putImageData(imageData, 0, 0);

    // Apply Overlays
    
    // 1. Scanlines (VHS)
    const scanlineHeight = Math.max(1, Math.floor(height / 400));
    ctx.fillStyle = `rgba(0, 0, 0, 0.15)`;
    for (let i = 0; i < height; i += scanlineHeight * 2) {
        ctx.fillRect(0, i, width, scanlineHeight);
    }

    // 2. Vignette (16mm Film effect)
    ctx.globalCompositeOperation = 'multiply';
    const cx = width / 2;
    const cy = height / 2;
    const radius = Math.max(cx, cy);
    const gradient = ctx.createRadialGradient(cx, cy, radius * 0.4, cx, cy, radius * 1.1);
    gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
    gradient.addColorStop(1, 'rgba(0, 0, 0, 0.7)');
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);
    ctx.globalCompositeOperation = 'source-over';

    // 3. Vertical Film Scratches (16mm Film effect)
    for (let i = 0; i < 5; i++) {
        let sX = Math.random() * width;
        // White scratch
        ctx.beginPath();
        ctx.moveTo(sX, 0);
        ctx.lineTo(sX + (Math.random() - 0.5) * 10, height);
        ctx.strokeStyle = `rgba(255, 255, 255, ${Math.random() * 0.15 + 0.05})`;
        ctx.lineWidth = Math.random() * 2 + 1;
        ctx.stroke();

        // Dark scratch
        sX = Math.random() * width;
        ctx.beginPath();
        ctx.moveTo(sX, 0);
        ctx.lineTo(sX + (Math.random() - 0.5) * 5, height);
        ctx.strokeStyle = `rgba(0, 0, 0, ${Math.random() * 0.2 + 0.05})`;
        ctx.lineWidth = Math.random() * 2 + 1;
        ctx.stroke();
    }

    // 4. VHS Camcorder OSD / Date Text
    if (Number(enableText) === 1) {
        const fontSize = Math.max(20, Math.floor(height * 0.05));
        ctx.font = `${fontSize}px "Courier New", Courier, monospace`;
        ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
        ctx.shadowColor = 'black';
        ctx.shadowBlur = width * 0.005;
        ctx.shadowOffsetX = width * 0.002;
        ctx.shadowOffsetY = width * 0.002;
        
        // "PLAY" icon
        ctx.fillText("PLAY \u25BA", width * 0.05, height * 0.1);
        
        // Timer/Date
        ctx.fillText("OCT. 26 1985", width * 0.05, height * 0.85);
        ctx.fillText("AM 01:20:00", width * 0.05, height * 0.85 + fontSize * 1.2);
        
        // Reset shadow
        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 vintage analog aesthetics to your photos, simulating the distinct looks of VHS camcorder footage and 16mm film. It uses advanced pixel manipulation to introduce effects such as chromatic aberration, horizontal jitter, scanlines, and tracking noise characteristic of VHS tapes. Additionally, it incorporates 16mm film qualities like color grading, film grain, vignetting, and vertical scratches. Users can also add classic On-Screen Display (OSD) elements like ‘PLAY’ icons and retro date/time stamps. This tool is ideal for creators looking to give their digital images a nostalgic, retro, or cinematic lo-fi feel for social media, artistic projects, or themed designs.

Leave a Reply

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