You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, intensity = 0.8, desaturation = 0.4, sepiaTone = 0.5, warmth = 0.15, vignetteStrength = 0.6, vignetteSoftness = 0.5) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Ensure the image is loaded and has dimensions
if (!originalImg || originalImg.width === 0 || originalImg.height === 0 || !originalImg.complete) {
console.error("Image not loaded or invalid.");
// Return a blank or minimal canvas if image is problematic
canvas.width = originalImg.width || 1;
canvas.height = originalImg.height || 1;
// Optionally draw a placeholder or clear it
ctx.clearRect(0, 0, canvas.width, canvas.height);
return canvas;
}
canvas.width = originalImg.width;
canvas.height = originalImg.height;
ctx.drawImage(originalImg, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
const width = canvas.width;
const height = canvas.height;
const centerX = width / 2;
const centerY = height / 2;
const maxImageRadius = Math.sqrt(centerX * centerX + centerY * centerY);
// Normalize parameters to be within [0, 1] if they are not, can be done here or assumed valid
intensity = Math.max(0, Math.min(1, intensity));
desaturation = Math.max(0, Math.min(1, desaturation));
sepiaTone = Math.max(0, Math.min(1, sepiaTone));
warmth = Math.max(0, Math.min(1, warmth));
vignetteStrength = Math.max(0, Math.min(1, vignetteStrength));
vignetteSoftness = Math.max(0, Math.min(1, vignetteSoftness));
for (let i = 0; i < data.length; i += 4) {
const originalR = data[i];
const originalG = data[i + 1];
const originalB = data[i + 2];
let r = originalR;
let g = originalG;
let b = originalB;
// 1. Desaturation
if (desaturation > 0) {
const gray = 0.299 * r + 0.587 * g + 0.114 * b;
r = r * (1 - desaturation) + gray * desaturation;
g = g * (1 - desaturation) + gray * desaturation;
b = b * (1 - desaturation) + gray * desaturation;
}
// Clamp after this stage before next calculations if values could go out of typical 0-255 range
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// 2. Sepia Tone
if (sepiaTone > 0) {
const sr = (r * 0.393) + (g * 0.769) + (b * 0.189);
const sg = (r * 0.349) + (g * 0.686) + (b * 0.168);
const sb = (r * 0.272) + (g * 0.534) + (b * 0.131);
r = r * (1 - sepiaTone) + sr * sepiaTone;
g = g * (1 - sepiaTone) + sg * sepiaTone;
b = b * (1 - sepiaTone) + sb * sepiaTone;
}
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// 3. Warmth
if (warmth > 0) {
r += 50 * warmth; // Add warmth to red
g += 25 * warmth; // Add less warmth to green
// b -= 10 * warmth; // Optionally cool down blue to enhance orange/yellow feel
}
// Clamp color-filtered values before vignette
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// 4. Vignette
let vignetteMultiplier = 1.0;
if (vignetteStrength > 0 && maxImageRadius > 0) {
const x = (i / 4) % width;
const y = Math.floor((i / 4) / width);
const dx = x - centerX;
const dy = y - centerY;
const dist = Math.sqrt(dx * dx + dy * dy);
const relativeDist = dist / maxImageRadius; // 0 at center, 1 at corners
// vignetteSoftness (0-1): 0 = sharp (high power), 1 = soft (low power)
// Power ranges from 1 (soft, linear falloff) to 4 (sharper, cubic-like falloff)
const vignettePower = 1 + (1 - vignetteSoftness) * 3;
const calculatedVignetteEffect = Math.pow(relativeDist, vignettePower) * vignetteStrength;
vignetteMultiplier = Math.max(0, 1.0 - calculatedVignetteEffect);
}
r *= vignetteMultiplier;
g *= vignetteMultiplier;
b *= vignetteMultiplier;
// Clamp after vignette (multiplication might slightly push out of bounds if vignetteMultiplier > 1, not in this case)
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// 5. Overall Intensity: Blend the fully filtered pixel (r,g,b) with the original pixel
data[i] = originalR * (1 - intensity) + r * intensity;
data[i+1] = originalG * (1 - intensity) + g * intensity;
data[i+2] = originalB * (1 - intensity) + b * intensity;
// Alpha (data[i+3]) is preserved from the original image
}
ctx.putImageData(imageData, 0, 0);
return canvas;
}
Apply Changes