Please bookmark this page to avoid losing your image tool!

Glitch Video File Editor

(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 = 20, enableScanlines = 1) {
    intensity = Number(intensity) || 0;
    const drawScanlines = Number(enableScanlines) === 1;

    const canvas = document.createElement('canvas');
    const width = originalImg.width;
    const height = originalImg.height;
    canvas.width = width;
    canvas.height = height;
    
    // willReadFrequently optimizes for getImageData/putImageData operations
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

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

    // If intensity is 0 or less, just return the original image on canvas
    if (intensity <= 0) return canvas;

    const maxOffset = intensity * 2;

    // --- 1. Slicing / Block Displacements (Simulates video tearing) ---
    const numBlocks = Math.floor(intensity * 1.5);
    for (let i = 0; i < numBlocks; i++) {
        const y = (Math.random() * height) | 0;
        const blockHeight = ((Math.random() * (height / 10)) | 0) + 2;
        const xOffset = ((Math.random() - 0.5) * maxOffset * 3) | 0;

        const safeY = Math.min(y, height - 1);
        const safeHeight = Math.max(1, Math.min(blockHeight, height - safeY));

        const blockData = ctx.getImageData(0, safeY, width, safeHeight);
        
        // Random black dropouts (missing video data)
        if (Math.random() < 0.1) {
            ctx.fillStyle = 'rgba(0,0,0,0.8)';
            ctx.fillRect(0, safeY, width, safeHeight);
        }

        // Draw the shifted image data
        ctx.putImageData(blockData, xOffset, safeY);
        
        // Handle horizontal wrap-around so the edge isn't just cut off
        if (xOffset > 0) {
            ctx.putImageData(blockData, xOffset - width, safeY);
        } else if (xOffset < 0) {
            ctx.putImageData(blockData, xOffset + width, safeY);
        }
    }

    // --- 2. Chromatic Aberration (RGB Shift) ---
    const imgData = ctx.getImageData(0, 0, width, height);
    const data = imgData.data;
    const outData = new Uint8ClampedArray(data);

    const baseRShift = (intensity * 0.5) | 0;
    const baseBShift = -(intensity * 0.5) | 0;

    for (let y = 0; y < height; y++) {
        let rShift = baseRShift;
        let bShift = baseBShift;
        
        // Introduce random jitter for a wavy edge effect
        if (Math.random() < 0.05) {
            rShift += ((Math.random() - 0.5) * intensity) | 0;
            bShift += ((Math.random() - 0.5) * intensity) | 0;
        }

        const yOffset = y * width;
        for (let x = 0; x < width; x++) {
            const i = (yOffset + x) << 2; // equivalent to * 4

            // Calculate shifted X positions with circular wrap-around handling
            let rx = (x - rShift) % width;
            if (rx < 0) rx += width;

            let bx = (x - bShift) % width;
            if (bx < 0) bx += width;

            const ri = (yOffset + rx) << 2;
            const bi = (yOffset + bx) << 2;

            outData[i] = data[ri];       // Set Red from shifted position
            // Green channel remains from original position `outData[i+1] = data[i+1]`
            outData[i+2] = data[bi+2];   // Set Blue from shifted position
        }
    }
    
    // Apply the RGB shifted data back to the canvas
    ctx.putImageData(new ImageData(outData, width, height), 0, 0);

    // --- 3. Digital Artifacts / Noise ---
    const noiseCount = (intensity * 5) | 0;
    const colors = ['#0ff', '#f0f', '#0f0', '#fff']; // Neon Cyan, Magenta, Green, White
    for (let i = 0; i < noiseCount; i++) {
        ctx.fillStyle = colors[(Math.random() * colors.length) | 0];
        ctx.globalAlpha = Math.random() * 0.4 + 0.1;
        const nx = (Math.random() * width) | 0;
        const ny = (Math.random() * height) | 0;
        const nw = ((Math.random() * intensity * 2) | 0) + 1;
        const nh = ((Math.random() * 4) | 0) + 1;
        ctx.fillRect(nx, ny, nw, nh);
    }
    
    // Reset alpha
    ctx.globalAlpha = 1.0;

    // --- 4. Scanlines (CRT Video Effect) ---
    if (drawScanlines) {
        // Calculate dynamic scanline transparency based on overall intensity
        const scanAlpha = Math.min(0.25, 0.05 + (intensity * 0.005));
        ctx.fillStyle = `rgba(0, 0, 0, ${scanAlpha})`;
        
        // Draw recurring horizontal lines starting from top
        for (let y = 0; y < height; y += 3) {
            ctx.fillRect(0, y, width, 1);
        }
    }

    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 Glitch Video File Editor is a digital manipulation tool designed to apply retro, distorted, and lo-fi visual effects to images. It simulates various video artifacts, including horizontal block displacements (video tearing), chromatic aberration (RGB color shifts), digital noise, and CRT-style scanlines. This tool is ideal for graphic designers, content creators, and artists looking to achieve a ‘glitch art’ aesthetic, nostalgic vaporwave visuals, or a corrupted media look for social media posts, music covers, and digital art projects.

Leave a Reply

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