Please bookmark this page to avoid losing your image tool!

Image Telephone Line Filter Effect 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.
function processImage(originalImg, scanlineHeight = 2, scanlineOpacity = 0.2, noiseIntensity = 25, desaturation = 1.0) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Set canvas dimensions. Use originalImg.width/height which are set after an Image object loads.
    // Fallback to naturalWidth (for <img> elements not yet sized) or a default if dimensions are zero.
    canvas.width = originalImg.width || originalImg.naturalWidth || 300;
    canvas.height = originalImg.height || originalImg.naturalHeight || 150;

    // 1. Draw the original image onto the canvas
    try {
        ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    } catch (e) {
        console.error("Error drawing original image:", e);
        // If drawing fails (e.g., image source is invalid or not loaded yet),
        // display an error message on the canvas.
        ctx.fillStyle = 'rgb(200, 200, 200)'; // Light gray background
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'rgb(255, 0, 0)'; // Red text
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.font = '16px Arial'; // A common font
        ctx.fillText("Error: Could not draw image.", canvas.width / 2, canvas.height / 2);
        return canvas; // Return canvas with error message
    }
    
    // 2. Attempt to Get image data for pixel manipulation
    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This can happen due to CORS restrictions if the image is from another origin.
        console.warn("Could not get ImageData (possibly due to CORS issue). Pixel manipulation (desaturation, noise) will be skipped.", e);
        // imageData remains undefined. The subsequent 'if (imageData)' block will be skipped.
        // Scanlines will still be drawn on the original image if their parameters are valid.
    }
    
    if (imageData) {
        const data = imageData.data;
        const len = data.length;

        // Sanitize/clamp parameter values for processing
        // Desaturation level, clamped to [0, 1]
        const effectiveDesaturation = Math.max(0, Math.min(1, desaturation));
        // Noise intensity, must be non-negative
        const effectiveNoiseIntensity = Math.max(0, noiseIntensity); 

        // 3. Apply desaturation and noise pixel by pixel
        for (let i = 0; i < len; i += 4) {
            let r = data[i];
            let g = data[i + 1];
            let b = data[i + 2];

            // Apply desaturation if specified
            if (effectiveDesaturation > 0) {
                // Standard luminance calculation for grayscale conversion
                const gray = 0.299 * r + 0.587 * g + 0.114 * b;
                // Linearly interpolate between original color and grayscale based on desaturation amount
                r = r * (1 - effectiveDesaturation) + gray * effectiveDesaturation;
                g = g * (1 - effectiveDesaturation) + gray * effectiveDesaturation;
                b = b * (1 - effectiveDesaturation) + gray * effectiveDesaturation;
            }

            // Apply noise if specified
            if (effectiveNoiseIntensity > 0) {
                // Generate a noise value for all channels (monochromatic noise)
                // Noise is random, centered at 0, ranging from -effectiveNoiseIntensity to +effectiveNoiseIntensity
                const noise = (Math.random() - 0.5) * 2 * effectiveNoiseIntensity;
                
                // Add noise and clamp to 0-255 range
                r = Math.max(0, Math.min(255, r + noise));
                g = Math.max(0, Math.min(255, g + noise));
                b = Math.max(0, Math.min(255, b + noise));
            }

            // Store modified (and rounded) pixel values back into the ImageData object
            data[i] = Math.round(r);
            data[i + 1] = Math.round(g);
            data[i + 2] = Math.round(b);
            // Alpha channel (data[i+3]) is preserved
        }
        // 4. Put the modified image data back onto the canvas
        ctx.putImageData(imageData, 0, 0);
    }


    // 5. Draw scan lines as an overlay
    // Sanitize scanline parameters
    // Scanline height, must be non-negative
    const effectiveScanlineHeight = Math.max(0, scanlineHeight); 
    // Scanline opacity, clamped to [0, 1]
    const effectiveScanlineOpacity = Math.max(0, Math.min(1, scanlineOpacity)); 

    if (effectiveScanlineHeight > 0 && effectiveScanlineOpacity > 0) {
        ctx.fillStyle = `rgba(0, 0, 0, ${effectiveScanlineOpacity})`; // Black scanlines
        // Loop through the canvas height, drawing a scanline then skipping a line of equal height
        for (let y = 0; y < canvas.height; y += effectiveScanlineHeight * 2) {
            ctx.fillRect(0, y, canvas.width, effectiveScanlineHeight);
        }
    }

    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 Telephone Line Filter Effect Tool allows users to apply a retro telephone line filter effect to images. This tool provides options for adjusting scanline height and opacity, as well as adding desaturation and noise to the image. It can be useful for creating vintage or stylized visuals, perfect for graphic design, artistic projects, or social media posts that aim for a nostalgic aesthetic.

Leave a Reply

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