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!
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.