Please bookmark this page to avoid losing your image tool!

Image CRT Lens Effect Enhancer For Nostalgic Wallpaper Design

(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.
/**
 * Enhances an image with a CRT lens effect featuring barrel distortion, vignette,
 * soft edge blur, scanlines, chromatic aberration, and luminous bloom to simulate
 * a retro display experience.
 *
 * @param {HTMLImageElement} originalImg The source image object.
 * @param {number} [distortion=0.2] The amount of barrel distortion (range ~0 to 1). Higher values create a more pronounced curve.
 * @param {number} [aberrationAmount=3.0] The strength of the chromatic aberration (color fringing) at the edges (range ~0 to 10).
 * @param {number} [bloomIntensity=0.3] The intensity of the luminous bloom effect for bright areas (range 0 to 1).
 * @param {number} [scanlineOpacity=0.1] The opacity of the horizontal scanlines (range 0 to 1). Set to 0 to disable.
 * @param {number} [vignetteIntensity=0.8] The darkness of the vignette at the corners (range 0 to 1).
 * @param {number} [vignetteSmoothness=0.7] The smoothness of the vignette's fade towards the center (range 0 to 1).
 * @returns {HTMLCanvasElement} A new canvas element displaying the processed image.
 */
function processImage(originalImg, distortion = 0.2, aberrationAmount = 3.0, bloomIntensity = 0.3, scanlineOpacity = 0.1, vignetteIntensity = 0.8, vignetteSmoothness = 0.7) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const w = originalImg.naturalWidth;
    const h = originalImg.naturalHeight;
    canvas.width = w;
    canvas.height = h;

    // --- Pass 1: Barrel Distortion & Chromatic Aberration ---
    // This pass redraws the image with a lens distortion effect.
    // It's performance-intensive as it processes pixels one by one.
    const sourceCanvas = document.createElement('canvas');
    sourceCanvas.width = w;
    sourceCanvas.height = h;
    const sourceCtx = sourceCanvas.getContext('2d', { willReadFrequently: true });
    sourceCtx.drawImage(originalImg, 0, 0, w, h);
    const sourceData = sourceCtx.getImageData(0, 0, w, h);
    const distortedData = ctx.createImageData(w, h);

    const cx = w / 2;
    const cy = h / 2;
    const maxDist = Math.sqrt(cx * cx + cy * cy);
    const aberration = aberrationAmount / 500.0;

    const getPixel = (data, x, y) => {
        x = Math.floor(x);
        y = Math.floor(y);
        if (x < 0 || x >= w || y < 0 || y >= h) {
            return [0, 0, 0, 0];
        }
        const i = (y * w + x) * 4;
        return [data.data[i], data.data[i + 1], data.data[i + 2], data.data[i + 3]];
    };

    for (let y = 0; y < h; y++) {
        for (let x = 0; x < w; x++) {
            const dx = x - cx;
            const dy = y - cy;
            const d = Math.sqrt(dx * dx + dy * dy);
            const normDist = d / maxDist;
            
            const k = distortion * Math.pow(normDist, 2);
            const mag = 1 / (1 + k);

            const sx = cx + dx * mag;
            const sy = cy + dy * mag;

            const sx_r = cx + dx * (mag - aberration);
            const sy_r = cy + dy * (mag - aberration);
            const sx_b = cx + dx * (mag + aberration);
            const sy_b = cy + dy * (mag + aberration);
            
            const r = getPixel(sourceData, sx_r, sy_r)[0];
            const g = getPixel(sourceData, sx, sy)[1];
            const b = getPixel(sourceData, sx_b, sy_b)[2];
            const a = getPixel(sourceData, sx, sy)[3];

            const dest_i = (y * w + x) * 4;
            distortedData.data[dest_i] = r;
            distortedData.data[dest_i + 1] = g;
            distortedData.data[dest_i + 2] = b;
            distortedData.data[dest_i + 3] = a;
        }
    }
    ctx.putImageData(distortedData, 0, 0);

    // --- Soft Edge Blur ---
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = w; tempCanvas.height = h;
    const tempCtx = tempCanvas.getContext('2d');
    tempCtx.filter = 'blur(0.5px)';
    tempCtx.drawImage(canvas, 0, 0);
    ctx.clearRect(0, 0, w, h);
    ctx.drawImage(tempCanvas, 0, 0);

    // --- Pass 2: Luminous Bloom ---
    if (bloomIntensity > 0) {
        const bloomCanvas = document.createElement('canvas');
        bloomCanvas.width = w; bloomCanvas.height = h;
        const bloomCtx = bloomCanvas.getContext('2d', { willReadFrequently: true });
        bloomCtx.drawImage(canvas, 0, 0);

        const bloomData = bloomCtx.getImageData(0, 0, w, h);
        const lumaThreshold = 180;
        for (let i = 0; i < bloomData.data.length; i += 4) {
            const luma = 0.2126 * bloomData.data[i] + 0.7152 * bloomData.data[i+1] + 0.0722 * bloomData.data[i+2];
            if (luma < lumaThreshold) {
                bloomData.data[i] = bloomData.data[i+1] = bloomData.data[i+2] = 0;
            }
        }
        bloomCtx.putImageData(bloomData, 0, 0);
        
        bloomCtx.filter = `blur(${bloomIntensity * 20}px)`;
        bloomCtx.drawImage(bloomCanvas, 0, 0);

        ctx.globalCompositeOperation = 'screen';
        ctx.globalAlpha = bloomIntensity;
        ctx.drawImage(bloomCanvas, 0, 0);
        ctx.globalCompositeOperation = 'source-over';
        ctx.globalAlpha = 1.0;
    }

    // --- Pass 3: Scanlines ---
    if (scanlineOpacity > 0) {
        ctx.fillStyle = `rgba(0, 0, 0, ${scanlineOpacity})`;
        for (let y = 0; y < h; y += 3) {
            ctx.fillRect(0, y, w, 1);
        }
    }

    // --- Pass 4: Vignette ---
    if (vignetteIntensity > 0) {
        const outerRadius = Math.sqrt(cx * cx + cy * cy);
        const gradient = ctx.createRadialGradient(cx, cy, outerRadius * (1 - vignetteSmoothness), cx, cy, outerRadius);
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        gradient.addColorStop(1, `rgba(0,0,0,${vignetteIntensity})`);
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, w, h);
    }
    
    // --- Pass 5: Curved Screen Bezel ---
    const cornerRadius = w * 0.04;
    ctx.fillStyle = 'black';
    ctx.beginPath();
    ctx.rect(0, 0, w, h);
    ctx.moveTo(cornerRadius, 0);
    ctx.lineTo(w - cornerRadius, 0);
    ctx.arcTo(w, 0, w, cornerRadius, cornerRadius);
    ctx.lineTo(w, h - cornerRadius);
    ctx.arcTo(w, h, w - cornerRadius, h, cornerRadius);
    ctx.lineTo(cornerRadius, h);
    ctx.arcTo(0, h, 0, h - cornerRadius, cornerRadius);
    ctx.lineTo(0, cornerRadius);
    ctx.arcTo(0, 0, cornerRadius, 0, cornerRadius);
    ctx.closePath();
    ctx.fill('evenodd');

    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 CRT Lens Effect Enhancer allows users to apply a vintage CRT display effect to images, transforming them into retro-style artwork. Features include barrel distortion, chromatic aberration, luminous bloom, scanlines, and vignette effects that can be finely adjusted. This tool is ideal for graphic designers, artists, and hobbyists looking to create nostalgic wallpapers, retro-themed artwork, or to evoke a sense of classic gaming aesthetics. Whether for personal projects or professional use, this effect adds a unique vintage charm to digital images.

Leave a Reply

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