You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, colorSettings = "2.00 2.00 2.00 0.80 0.80 0.80 0.08 0.08 0.08", brightness = 0, contrast = 0, saturation = 1) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0);
// Extract exactly 9 numeric values from the string:
// [Multiplier R, G, B], [Gamma R, G, B], [Offset R, G, B]
let nums = String(colorSettings).replace(/[^\d.\-,\s]/g, '').trim().split(/[\s,]+/).filter(Boolean).map(parseFloat);
if (nums.length < 9) {
// Default to neutral/no-change parameters if the configuration is incomplete
nums = [1, 1, 1, 1, 1, 1, 0, 0, 0];
}
const multRow = [nums[0], nums[1], nums[2]];
const gammaRow = [nums[3], nums[4], nums[5]];
const offsetRow = [nums[6], nums[7], nums[8]];
// General adjustment factors
const bAdj = parseFloat(brightness) || 0;
const cAdj = parseFloat(contrast) || 0;
const sAdj = isNaN(parseFloat(saturation)) ? 1.0 : parseFloat(saturation);
// Derived uniform contrast multiplier (using standard -255 to 255 scaling factor)
const cFactor = (259 * (cAdj + 255)) / (255 * (259 - cAdj));
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imgData.data;
// Apply color correction per pixel
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// 1. Initial Contrast & Brightness (-255 to +255 range baseline adjustments)
if (cAdj !== 0) {
r = cFactor * (r - 128) + 128;
g = cFactor * (g - 128) + 128;
b = cFactor * (b - 128) + 128;
}
r += bAdj;
g += bAdj;
b += bAdj;
// Normalize color channels to 0.0 - 1.0 for node-based exponential manipulation
r /= 255.0;
g /= 255.0;
b /= 255.0;
// 2. Multiplier (Gain), Offset (Lift), and Power (Gamma)
// Formula: Output = Math.max(0, Input * Multiplier + Offset) ^ Gamma
r = Math.pow(Math.max(0, r * multRow[0] + offsetRow[0]), gammaRow[0]);
g = Math.pow(Math.max(0, g * multRow[1] + offsetRow[1]), gammaRow[1]);
b = Math.pow(Math.max(0, b * multRow[2] + offsetRow[2]), gammaRow[2]);
// 3. Saturation Calculation
if (sAdj !== 1.0) {
const lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
r = lum + sAdj * (r - lum);
g = lum + sAdj * (g - lum);
b = lum + sAdj * (b - lum);
}
// Clamp securely and stretch back to 0-255 scale
data[i] = Math.min(255, Math.max(0, r * 255));
data[i + 1] = Math.min(255, Math.max(0, g * 255));
data[i + 2] = Math.min(255, Math.max(0, b * 255));
}
ctx.putImageData(imgData, 0, 0);
return canvas;
}
Apply Changes