You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, blendIntensity = "0.6", glowRadius = "12", vignetteStrength = "0.7", grainLevel = "0.15") {
// Parse and validate parameters
const intensity = isNaN(parseFloat(blendIntensity)) ? 0.6 : Math.max(0, Math.min(1, parseFloat(blendIntensity)));
const blur = isNaN(parseFloat(glowRadius)) ? 12 : Math.max(0, parseFloat(glowRadius));
const vignette = isNaN(parseFloat(vignetteStrength)) ? 0.7 : Math.max(0, Math.min(1, parseFloat(vignetteStrength)));
const grain = isNaN(parseFloat(grainLevel)) ? 0.15 : Math.max(0, Math.min(1, parseFloat(grainLevel)));
const canvas = document.createElement('canvas');
const width = originalImg.width || originalImg.naturalWidth;
const height = originalImg.height || originalImg.naturalHeight;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Failsafe for invalid dimensions
if (!width || !height) return canvas;
// Step 1: Base Layer - Classic Black and White, High Contrast
ctx.filter = 'grayscale(100%) contrast(115%) brightness(105%)';
ctx.drawImage(originalImg, 0, 0, width, height);
// Step 2: "Marlene's Dream" Glow / Soft B&W Focus
if (intensity > 0) {
ctx.globalCompositeOperation = 'screen';
ctx.globalAlpha = intensity;
ctx.filter = `grayscale(100%) blur(${blur}px) contrast(140%) brightness(110%)`;
ctx.drawImage(originalImg, 0, 0, width, height);
}
// Reset context properties
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 1.0;
ctx.filter = 'none';
// Step 3: Cinematic Vignette to draw focus to the center
if (vignette > 0) {
ctx.globalCompositeOperation = 'multiply';
const cx = width / 2;
const cy = height / 2;
const r = Math.max(cx, cy);
const gradient = ctx.createRadialGradient(cx, cy, r * 0.4, cx, cy, r * 1.3);
const edgeShade = Math.round(255 * (1 - vignette));
// White does practically nothing in 'multiply' mode, preserving the center brightness
gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
// Darkened edges based on vignette strength
gradient.addColorStop(1, `rgba(${edgeShade}, ${edgeShade}, ${edgeShade}, 1)`);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
}
// Step 4: Subtle Vintage Film Grain
if (grain > 0) {
ctx.globalCompositeOperation = 'overlay';
ctx.globalAlpha = grain;
const noiseCanvas = document.createElement('canvas');
noiseCanvas.width = width;
noiseCanvas.height = height;
const noiseCtx = noiseCanvas.getContext('2d');
const noiseData = noiseCtx.createImageData(width, height);
// Generate monochrome noise directly
for (let i = 0; i < noiseData.data.length; i += 4) {
const val = Math.random() * 255 | 0;
noiseData.data[i] = val; // R
noiseData.data[i+1] = val; // G
noiseData.data[i+2] = val; // B
noiseData.data[i+3] = 255; // A
}
noiseCtx.putImageData(noiseData, 0, 0);
ctx.drawImage(noiseCanvas, 0, 0);
}
// Restore context properties
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 1.0;
return canvas;
}
Apply Changes