Please bookmark this page to avoid losing your image tool!

Image TV Simulator Line Synchronization Tool

(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.
/**
 * Simulates an old CRT TV's line synchronization issue, creating a glitchy,
 * horizontally-shifting effect on the image. It also adds optional scanlines,
 * noise, and a vignette for a more authentic retro feel.
 *
 * @param {Image} originalImg The original HTML Image object to process.
 * @param {number} [shiftAmount=25] The maximum horizontal shift in pixels for the distortion effect. Higher values create a more intense "tear".
 * @param {number} [distortionFrequency=0.05] Controls the vertical frequency of the rolling distortion wave. Smaller values create wider, slower waves.
 * @param {number} [glitchChance=0.02] The probability (0 to 1) of a sharp, random glitch occurring on any given line.
 * @param {string} [addScanlines="true"] Whether to add semi-transparent horizontal scanlines. Accepts "true" or "false".
 * @param {number} [vignetteAmount=0.4] The intensity of the dark vignette effect around the edges (0 to 1). 0 means no vignette.
 * @returns {HTMLCanvasElement} A new canvas element with the TV simulator effect applied.
 */
function processImage(originalImg, shiftAmount = 25, distortionFrequency = 0.05, glitchChance = 0.02, addScanlines = "true", vignetteAmount = 0.4) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });
    const width = originalImg.naturalWidth;
    const height = originalImg.naturalHeight;
    canvas.width = width;
    canvas.height = height;

    // Use current time as a seed to make the distortion animate on subsequent calls
    const time = Date.now() / 1000;

    // --- 1. Apply Line Synchronization Distortion ---
    for (let y = 0; y < height; y++) {
        // Calculate a sine wave-based shift for a rolling bar effect.
        // Combining multiple waves creates a more chaotic, less uniform pattern.
        const wave1 = Math.sin((y * distortionFrequency) + time);
        const wave2 = Math.cos((y * distortionFrequency * 0.3) + time * 0.7);
        let horizontalShift = Math.floor(((wave1 + wave2) / 2) * shiftAmount);

        // Add some random, sharp glitches for extra effect
        if (Math.random() < glitchChance) {
            horizontalShift += Math.floor((Math.random() - 0.5) * shiftAmount * 3);
        }

        // Calculate the source and destination rectangles for drawing the shifted line
        const sx = Math.max(0, -horizontalShift);
        const dx = Math.max(0, horizontalShift);
        const sWidth = width - Math.abs(horizontalShift);

        if (sWidth > 0) {
            // Draw a 1-pixel high slice of the original image at the shifted position
            ctx.drawImage(
                originalImg,
                sx, y, sWidth, 1, // source rect (from original image)
                dx, y, sWidth, 1 // destination rect (on the canvas)
            );
        }
    }

    // --- 2. Add Static Noise ---
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;
    for (let i = 0; i < data.length; i += 4) {
        // Only apply noise to filled pixels to avoid making blank areas gray
        if (data[i + 3] > 0) {
            const noise = (Math.random() - 0.5) * 30; // Noise intensity
            data[i] = Math.max(0, Math.min(255, data[i] + noise));
            data[i + 1] = Math.max(0, Math.min(255, data[i + 1] + noise));
            data[i + 2] = Math.max(0, Math.min(255, data[i + 2] + noise));
        }
    }
    ctx.putImageData(imageData, 0, 0);


    // --- 3. Optional Scanlines ---
    const useScanlines = String(addScanlines).toLowerCase() === "true";
    if (useScanlines) {
        ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
        for (let y = 0; y < height; y += 3) {
            ctx.fillRect(0, y, width, 1);
        }
    }

    // --- 4. Optional Vignette ---
    const clampedVignette = Math.max(0, Math.min(1, vignetteAmount));
    if (clampedVignette > 0) {
        const outerRadius = Math.sqrt(width ** 2 + height ** 2) / 2;
        const innerRadius = outerRadius * (1 - clampedVignette);

        const gradient = ctx.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,${clampedVignette * 0.9})`);

        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, width, height);
    }

    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

The Image TV Simulator Line Synchronization Tool allows users to apply retro CRT TV distortion effects to images. It creates a glitchy appearance with horizontal shifting, simulating line synchronization issues often seen in old television displays. Users can modify parameters such as the intensity of the shifting effect, the frequency of the distortion, the chance of random glitches, and whether to include scanlines and a vignette effect. This tool is ideal for artists, designers, and content creators looking to add a nostalgic touch to their images, or to create unique visual styles reminiscent of vintage television broadcasts.

Leave a Reply

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