You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, sepiaStrength = 0.6, contrastLevel = 15, brightnessAdjust = -10, vignetteIntensity = 0.5, vignetteSoftness = 0.7) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Ensure originalImg dimensions are available
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
if (imgWidth === 0 || imgHeight === 0) {
// If image dimensions are not available (e.g., image not loaded), return a minimal canvas.
// This prevents errors but the caller should ideally ensure the image is loaded.
console.warn("Image for processing has zero width or height. Ensure the image is fully loaded.");
canvas.width = 1;
canvas.height = 1;
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Get image data for pixel manipulation
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
const len = data.length;
// Normalize parameters to sensible ranges
const SStrength = Math.max(0, Math.min(1, sepiaStrength));
// Contrast: safe range for the formula, e.g., map user input (-100 to 100) to this.
// Here, we assume `contrastLevel` is already in a suitable range (e.g. -100 to 100).
// Clamp to avoid division by zero or extreme behavior near +/-259.
const CLevel = Math.max(-254.9, Math.min(254.9, contrastLevel));
const BAdjust = brightnessAdjust; // Can be positive or negative, e.g. -255 to 255
const VIntensity = Math.max(0, Math.min(1, vignetteIntensity));
const VSoftness = Math.max(0, Math.min(1, vignetteSoftness));
// Process each pixel
for (let i = 0; i < len; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// 1. Apply Sepia Tone
if (SStrength > 0) {
const R_orig = r, G_orig = g, B_orig = b;
// Standard sepia weights
const sr = (R_orig * 0.393) + (G_orig * 0.769) + (B_orig * 0.189);
const sg = (R_orig * 0.349) + (G_orig * 0.686) + (B_orig * 0.168);
const sb = (R_orig * 0.272) + (G_orig * 0.534) + (B_orig * 0.131);
// Interpolate between original and sepia based on strength
r = R_orig * (1 - SStrength) + sr * SStrength;
g = G_orig * (1 - SStrength) + sg * SStrength;
b = B_orig * (1 - SStrength) + sb * SStrength;
}
// 2. Adjust Contrast
if (CLevel !== 0) {
const factor = (259 * (CLevel + 255)) / (255 * (259 - CLevel));
r = factor * (r - 128) + 128;
g = factor * (g - 128) + 128;
b = factor * (b - 128) + 128;
}
// 3. Adjust Brightness
if (BAdjust !== 0) {
r += BAdjust;
g += BAdjust;
b += BAdjust;
}
// Clamp final RGB values to [0, 255]
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));
// Alpha (data[i+3]) remains unchanged
}
// Put the modified pixel data back onto the canvas
ctx.putImageData(imageData, 0, 0);
// 4. Apply Vignette effect
if (VIntensity > 0) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Calculate outer radius for vignette (e.g., to cover corners using hypotenuse)
const outerRadius = Math.sqrt(centerX * centerX + centerY * centerY);
// vignetteSoftness (0 to 1): 0 = sharp edge, 1 = very soft edge
// Map vignetteSoftness to the start radius (r0) of the radial gradient.
// min_r0_factor: for softest vignette (gradient starts near center)
// max_r0_factor: for sharpest vignette (gradient starts near edge)
const min_r0_factor = 0.1; // e.g., gradient starts at 10% of outerRadius for VSoftness = 1
const max_r0_factor = 0.85; // e.g., gradient starts at 85% of outerRadius for VSoftness = 0
// If VSoftness = 1 (soft), actual_r0_factor approaches min_r0_factor.
// If VSoftness = 0 (sharp), actual_r0_factor approaches max_r0_factor.
const actual_r0_factor = min_r0_factor + (max_r0_factor - min_r0_factor) * (1 - VSoftness);
const r0 = outerRadius * actual_r0_factor; // Inner radius of the gradient
const r1 = outerRadius; // Outer radius of the gradient
if (r0 < r1 && r1 > 0) { // Ensure r0 is less than r1 and outer radius is positive for a valid gradient
const gradient = ctx.createRadialGradient(centerX, centerY, r0, centerX, centerY, r1);
gradient.addColorStop(0, 'rgba(0,0,0,0)'); // Transparent at the inner part
gradient.addColorStop(1, `rgba(0,0,0,${VIntensity})`); // Target vignette color/opacity at the outer part
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
return canvas;
}
Apply Changes