You can edit the below JavaScript code to customize the image tool.
function processImage(
originalImg,
saturation = 0.85, // 0.0 (grayscale) to 1.0 (original) to 2.0 (oversaturated)
contrast = 0.95, // 0.0 (gray) to 1.0 (original) to 2.0 (high contrast)
brightness = 5, // Integer or float, effects pixel values from -255 to 255
sepia = 0.15, // 0.0 (none) to 1.0 (full sepia-like tint)
redChannelMultiplier = 1.05, // e.g., 1.0 to 1.2. Boosts red tones.
blueChannelMultiplier = 0.95, // e.g., 0.8 to 1.0. Reduces blue tones, can make image warmer or shift towards yellow/green.
grain = 0.03, // 0.0 (none) to e.g. 0.1 (moderate grain). Scales noise level.
vignetteStrength = 0.4 // 0.0 (none) to 1.0 (strong darkening at edges)
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const w = originalImg.naturalWidth || originalImg.width;
const h = originalImg.naturalHeight || originalImg.height;
canvas.width = w;
canvas.height = h;
ctx.drawImage(originalImg, 0, 0, w, h);
const imageData = ctx.getImageData(0, 0, w, h);
const data = imageData.data; // Uint8ClampedArray: [R, G, B, A, R, G, B, A, ...]
const centerX = w / 2;
const centerY = h / 2;
// Calculate the furthest distance from the center to a corner
const maxDist = Math.sqrt(centerX * centerX + centerY * centerY);
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// --- TONAL ADJUSTMENTS ---
// 1. Brightness (additive)
// This shifts all pixel values up or down.
r += brightness;
g += brightness;
b += brightness;
// 2. Contrast (multiplicative around mid-gray)
// Mid-gray is 128. Pixels darker than 128 become darker, lighter become lighter.
// factor < 1 reduces contrast, factor > 1 increases it.
r = (r - 128) * contrast + 128;
g = (g - 128) * contrast + 128;
b = (b - 128) * contrast + 128;
// --- COLOR ADJUSTMENTS ---
// 3. Saturation
// Luminance (perceptual brightness of the color)
const lum = 0.299 * r + 0.587 * g + 0.114 * b;
// Interpolate between the grayscale version (lum) and the original color
// saturation = 0: grayscale, saturation = 1: original, saturation > 1: oversaturated
r = lum + saturation * (r - lum);
g = lum + saturation * (g - lum);
b = lum + saturation * (b - lum);
// 4. Sepia Tint
// Applies a warm, brownish tint.
if (sepia > 0) {
const originalR = r; // Use values after previous adjustments
const originalG = g;
const originalB = b;
// Standard sepia RGB transformation values
const sr = (originalR * 0.393) + (originalG * 0.769) + (originalB * 0.189);
const sg = (originalR * 0.349) + (originalG * 0.686) + (originalB * 0.168);
const sb = (originalR * 0.272) + (originalG * 0.534) + (originalB * 0.131);
// Interpolate between original color and full sepia based on sepia strength
r = originalR * (1 - sepia) + sr * sepia;
g = originalG * (1 - sepia) + sg * sepia;
b = originalB * (1 - sepia) + sb * sepia;
}
// 5. Channel Multipliers (for specific color cast - e.g., slightly more red, less blue)
// This can help achieve a "faded film" or specific retro color palette.
r *= redChannelMultiplier;
// g *= greenChannelMultiplier; // Example: Could add a green multiplier parameter
b *= blueChannelMultiplier;
// --- EFFECTS ---
// 6. Vignette
// Darkens the corners/edges of the image.
if (vignetteStrength > 0) {
const x = (i / 4) % w; // Current pixel's x coordinate
const y = Math.floor((i / 4) / w); // Current pixel's y coordinate
const dx = x - centerX;
const dy = y - centerY;
const dist = Math.sqrt(dx * dx + dy * dy);
// Normalize distance (0 at center, 1 at furthest corner/edge)
const normDist = dist / maxDist;
// Vignette amount fades from 1 (no change at center) to (1 - vignetteStrength) at the maxDist.
// Math.pow(normDist, power) controls the falloff curve. Higher power = faster falloff from center.
// A power of 1.5 to 2.0 usually gives a nice smooth vignette.
const vigAmount = 1.0 - Math.pow(normDist, 1.8) * vignetteStrength;
r *= vigAmount;
g *= vigAmount;
b *= vigAmount;
}
// 7. Film Grain
// Adds random noise to simulate film grain.
if (grain > 0) {
// Generate noise between -0.5 and 0.5, then scale by (255 * grain amount)
// So, if grain is 0.1, noise is up to +/- 25.5
const noise = (Math.random() - 0.5) * 255 * grain;
r += noise;
g += noise;
b += noise;
}
// Clamp values to the 0-255 range for each color channel
data[i] = Math.max(0, Math.min(255, r));
data[i + 1] = Math.max(0, Math.min(255, g));
data[i + 2] = Math.max(0, Math.min(255, b));
// data[i+3] is alpha, typically left unchanged for an opaque filter
}
ctx.putImageData(imageData, 0, 0);
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 80’s Retro Photo Filter is a web-based tool designed to apply a nostalgic 1980s film effect to images. Users can modify various parameters such as saturation, contrast, brightness, sepia tone, and granular effects to achieve a retro aesthetic. This tool is perfect for enhancing photographs to give them a vintage look, creating stylized content for social media, or for personal projects where a retro feel is desired. Whether you’re a graphic designer, social media influencer, or just looking to have fun with your photos, this tool allows you to transform modern images into charming retro-style visuals.