Please bookmark this page to avoid losing your image tool!

Image TV Simulator For Vegas Pro

(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, distortion = 0.2, scanlineOpacity = 0.15, scanlineSpacing = 3, vignetteStrength = 0.8, staticAmount = 25, desaturation = 0.5, tintColor = '#33ff33', tintOpacity = 0.05) {

    const {
        width,
        height
    } = originalImg;

    // Helper to parse hex color strings
    const hexToRgb = (hex) => {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16),
        } : null;
    };

    // Clamp parameters to valid ranges
    distortion = Math.max(0, Math.min(1, distortion));
    scanlineOpacity = Math.max(0, Math.min(1, scanlineOpacity));
    scanlineSpacing = Math.max(1, scanlineSpacing);
    vignetteStrength = Math.max(0, Math.min(1, vignetteStrength));
    staticAmount = Math.max(0, Math.min(255, staticAmount));
    desaturation = Math.max(0, Math.min(1, desaturation));
    tintOpacity = Math.max(0, Math.min(1, tintOpacity));

    const tint = hexToRgb(tintColor);

    const destCanvas = document.createElement('canvas');
    destCanvas.width = width;
    destCanvas.height = height;
    const destCtx = destCanvas.getContext('2d');

    // --- 1. Apply barrel distortion ---
    if (distortion > 0) {
        const sourceCanvas = document.createElement('canvas');
        sourceCanvas.width = width;
        sourceCanvas.height = height;
        const sourceCtx = sourceCanvas.getContext('2d', { willReadFrequently: true });
        sourceCtx.drawImage(originalImg, 0, 0);
        const sourceData = sourceCtx.getImageData(0, 0, width, height).data;

        const destImageData = destCtx.createImageData(width, height);
        const destData = destImageData.data;

        const centerX = width / 2;
        const centerY = height / 2;
        const k = -distortion; // Negative k for barrel distortion

        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                // Normalize coordinates to [-0.5, 0.5]
                const nX = (x - centerX) / width;
                const nY = (y - centerY) / height;
                const r2 = nX * nX + nY * nY;

                // Apply inverse distortion formula
                const factor = 1 + k * r2;
                const sX = centerX + nX * width / factor;
                const sY = centerY + nY * height / factor;

                const destIndex = (y * width + x) * 4;

                if (sX >= 0 && sX < width && sY >= 0 && sY < height) {
                    // Nearest neighbor sampling for a retro look
                    const sourceX = Math.floor(sX);
                    const sourceY = Math.floor(sY);
                    const sourceIndex = (sourceY * width + sourceX) * 4;

                    destData[destIndex] = sourceData[sourceIndex];
                    destData[destIndex + 1] = sourceData[sourceIndex + 1];
                    destData[destIndex + 2] = sourceData[sourceIndex + 2];
                    destData[destIndex + 3] = sourceData[sourceIndex + 3];
                } else {
                    // Pixels outside the source are black
                    destData[destIndex] = 0;
                    destData[destIndex + 1] = 0;
                    destData[destIndex + 2] = 0;
                    destData[destIndex + 3] = 255;
                }
            }
        }
        destCtx.putImageData(destImageData, 0, 0);
    } else {
        // If no distortion, just draw the image
        destCtx.drawImage(originalImg, 0, 0);
    }

    // --- 2. Apply pixel-level effects (Color, Static) ---
    const imageData = destCtx.getImageData(0, 0, width, height);
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];

        // Desaturation
        if (desaturation > 0) {
            const gray = 0.299 * r + 0.587 * g + 0.114 * b;
            r = r * (1 - desaturation) + gray * desaturation;
            g = g * (1 - desaturation) + gray * desaturation;
            b = b * (1 - desaturation) + gray * desaturation;
        }

        // Tint
        if (tint && tintOpacity > 0) {
            r = r * (1 - tintOpacity) + tint.r * tintOpacity;
            g = g * (1 - tintOpacity) + tint.g * tintOpacity;
            b = b * (1 - tintOpacity) + tint.b * tintOpacity;
        }
        
        // Static/Noise
        if (staticAmount > 0) {
            const noise = (Math.random() - 0.5) * staticAmount;
            r += noise;
            g += noise;
            b += noise;
        }

        // Clamp values to 0-255 range
        data[i] = Math.max(0, Math.min(255, r));
        data[i + 1] = Math.max(0, Math.min(255, g));
        data[i + 2] = Math.max(0, Math.min(255, b));
    }
    destCtx.putImageData(imageData, 0, 0);

    // --- 3. Apply overlays (Scanlines, Vignette) ---

    // Scan lines
    if (scanlineOpacity > 0) {
       destCtx.fillStyle = `rgba(0, 0, 0, ${scanlineOpacity})`;
       for (let y = 0; y < height; y += scanlineSpacing) {
           destCtx.fillRect(0, y, width, 1);
       }
    }

    // Vignette
    if (vignetteStrength > 0) {
        const outerRadius = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(height / 2, 2));
        // A smaller inner radius makes the center clear area smaller
        const innerRadius = outerRadius * 0.3;
        const gradient = destCtx.createRadialGradient(
            width / 2, height / 2, innerRadius,
            width / 2, height / 2, outerRadius
        );
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        gradient.addColorStop(1, `rgba(0,0,0,${vignetteStrength})`);
        
        destCtx.fillStyle = gradient;
        destCtx.fillRect(0, 0, width, height);
    }
    
    return destCanvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image TV Simulator for Vegas Pro is a tool that enables users to apply retro TV effects to images. This tool includes features such as barrel distortion, scanlines, and vignette effects, enhancing images to give them an authentic vintage television look. Users can customize parameters like distortion level, scanline opacity, and static noise to achieve their desired aesthetic. This tool is particularly useful for video editors, graphic designers, and content creators looking to add nostalgic, retro elements to visual projects.

Leave a Reply

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