Please bookmark this page to avoid losing your image tool!

Image Video Effects Enhancer

(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.
/**
 * Applies various video-style effects to an image.
 *
 * @param {Image} originalImg The original javascript Image object.
 * @param {string} effectName The name of the effect to apply. Available effects: 'grayscale', 'sepia', 'invert', 'posterize', 'noise', 'scanlines', 'vignette', 'blur', 'vhs', 'none'.
 * @param {number} intensity A general-purpose intensity value for the effect (e.g., blur amount, noise level). Range and effect vary by filter. Recommended 1-10.
 * @returns {HTMLCanvasElement} A new canvas element with the effect applied.
 */
function processImage(originalImg, effectName = 'none', intensity = 5) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const w = originalImg.naturalWidth;
    const h = originalImg.naturalHeight;
    canvas.width = w;
    canvas.height = h;

    const effect = effectName.toLowerCase();

    // Early exit for no effect
    if (effect === 'none') {
        ctx.drawImage(originalImg, 0, 0, w, h);
        return canvas;
    }

    // Handle filter-based effects first, as they are applied before drawing the image
    if (effect === 'blur') {
        // Clamp intensity to a reasonable blur radius (0-20px)
        const blurAmount = Math.max(0, Math.min(20, intensity));
        ctx.filter = `blur(${blurAmount}px)`;
        ctx.drawImage(originalImg, 0, 0, w, h);
        return canvas; // Return early, as filter is applied
    }

    // For all other effects, draw the image onto the canvas first
    ctx.drawImage(originalImg, 0, 0, w, h);

    // --- PIXEL MANIPULATION EFFECTS ---
    const pixelEffects = ['grayscale', 'sepia', 'invert', 'posterize', 'noise'];
    if (pixelEffects.includes(effect)) {
        const imageData = ctx.getImageData(0, 0, w, h);
        const data = imageData.data;
        for (let i = 0; i < data.length; i += 4) {
            let r = data[i],
                g = data[i + 1],
                b = data[i + 2];

            if (effect === 'grayscale') {
                const avg = 0.299 * r + 0.587 * g + 0.114 * b;
                data[i] = data[i + 1] = data[i + 2] = avg;
            } else if (effect === 'sepia') {
                const tr = 0.393 * r + 0.769 * g + 0.189 * b;
                const tg = 0.349 * r + 0.686 * g + 0.168 * b;
                const tb = 0.272 * r + 0.534 * g + 0.131 * b;
                data[i] = Math.min(255, tr);
                data[i + 1] = Math.min(255, tg);
                data[i + 2] = Math.min(255, tb);
            } else if (effect === 'invert') {
                data[i] = 255 - r;
                data[i + 1] = 255 - g;
                data[i + 2] = 255 - b;
            } else if (effect === 'posterize') {
                // Clamp intensity to a useful number of color levels (2-32)
                const levels = Math.max(2, Math.min(32, Math.round(intensity)));
                const step = 255 / (levels - 1);
                data[i] = Math.round(r / step) * step;
                data[i + 1] = Math.round(g / step) * step;
                data[i + 2] = Math.round(b / step) * step;
            } else if (effect === 'noise') {
                // Clamp intensity to control noise amount (0-100)
                const noiseAmount = Math.max(0, Math.min(100, intensity));
                const noise = (Math.random() - 0.5) * noiseAmount;
                data[i] = Math.max(0, Math.min(255, r + noise));
                data[i + 1] = Math.max(0, Math.min(255, g + noise));
                data[i + 2] = Math.max(0, Math.min(255, b + noise));
            }
        }
        ctx.putImageData(imageData, 0, 0);
    }

    // --- OVERLAY / COMPOSITE EFFECTS ---
    if (effect === 'scanlines') {
        const lineGap = Math.max(2, Math.min(10, Math.round(intensity)));
        const lineHeight = Math.floor(lineGap / 2);
        ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
        for (let y = 0; y < h; y += lineGap) {
            ctx.fillRect(0, y, w, lineHeight);
        }
    } else if (effect === 'vignette') {
        // Clamp intensity to a valid alpha value (0.0 - 1.0)
        const vignetteAmount = Math.max(0, Math.min(1, intensity / 10));
        const outerRadius = Math.sqrt(w * w + h * h) / 2;
        const gradient = ctx.createRadialGradient(w / 2, h / 2, h / 3, w / 2, h / 2, outerRadius);
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        gradient.addColorStop(0.5, 'rgba(0,0,0,0)'); // Make the center clear
        gradient.addColorStop(1, `rgba(0,0,0,${vignetteAmount})`);
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);
    } else if (effect === 'vhs') {
        // 1. Chromatic Aberration
        const imageData = ctx.getImageData(0, 0, w, h);
        const data = imageData.data;
        const originalData = new Uint8ClampedArray(data); // Create a copy to read from
        const offset = Math.round(intensity) * 4; // 1 pixel = 4 bytes (RGBA)
        
        for (let i = 0; i < data.length; i += 4) {
            // Set red channel from a pixel to the left
            const rIndex = i - offset;
            if (rIndex >= 0) {
                 data[i] = originalData[rIndex];
            }
            // Set blue channel from a pixel to the right
            const bIndex = i + offset;
            if (bIndex < data.length) {
                 data[i + 2] = originalData[bIndex + 2];
            }
        }
        ctx.putImageData(imageData, 0, 0);

        // 2. Scanlines
        ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
        for (let y = 0; y < h; y += 4) {
            ctx.fillRect(0, y, w, 2);
        }

        // 3. Random horizontal glitch
        const glitchCount = 15;
        const maxGlitchOffset = 40;
        for (let i = 0; i < glitchCount; i++) {
            const y = Math.random() * h;
            const stripHeight = Math.random() * 20 + 1;
            const xOffset = (Math.random() - 0.5) * maxGlitchOffset;
            try {
                const stripData = ctx.getImageData(0, y, w, stripHeight);
                ctx.putImageData(stripData, xOffset, y);
            } catch (e) {
                // Ignore errors from getImageData if y/height are out of bounds
            }
        }
    }

    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 Video Effects Enhancer is a versatile tool designed to apply a variety of video-style effects to images, transforming their appearance creatively. Users can choose from effects such as grayscale, sepia, inversion, posterization, and more, each adjustable in intensity to achieve the desired visual outcome. This tool can be utilized for enhancing images in graphic design, creating artistic content for social media, or adding stylistic elements to visual presentations. Whether you’re looking to achieve a vintage look with sepia tones or a dynamic VHS effect, this enhancer provides a user-friendly way to customize your images.

Leave a Reply

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