You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, saturationInput = 1.8, contrastInput = 1.2) {
// Ensure parameters are numbers, and handle potential string inputs.
// Convert inputs to numbers. If conversion fails (e.g., "abc"), result is NaN.
const parsedSaturation = Number(saturationInput);
const parsedContrast = Number(contrastInput);
// Validate converted numbers. If NaN, use the default values.
// Also, ensure boost factors are non-negative.
const actualSaturationBoost = isNaN(parsedSaturation) ? 1.8 : Math.max(0, parsedSaturation);
const actualContrastBoost = isNaN(parsedContrast) ? 1.2 : Math.max(0, parsedContrast);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Use naturalWidth/Height if available, otherwise fallback to width/height.
// This is robust for HTMLImageElement objects.
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
// If image dimensions are invalid or image not loaded, return an empty canvas.
if (imgWidth === 0 || imgHeight === 0) {
canvas.width = 0;
canvas.height = 0;
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
// Get the pixel data from the canvas
// For potentially frequent reads, { willReadFrequently: true } can be a hint in some browsers.
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data; // Uint8ClampedArray: [R, G, B, A, R, G, B, A, ...]
// Iterate over each pixel (each pixel consists of 4 values: R, G, B, A)
for (let i = 0; i < data.length; i += 4) {
// Get current pixel's R, G, B values and normalize them to [0, 1] range
let r = data[i] / 255;
let g = data[i + 1] / 255;
let b = data[i + 2] / 255;
// Alpha component (data[i + 3]) is usually left unchanged for this kind of filter
// 1. Apply Saturation Boost
// Calculate luminance (perceived brightness of the pixel)
const lum = 0.299 * r + 0.587 * g + 0.114 * b;
// Interpolate between the luminance (grayscale version) and the original color
// C_saturated = lum + saturationBoost * (C_original - lum)
// If saturationBoost = 0, C_saturated = lum (grayscale)
// If saturationBoost = 1, C_saturated = C_original (no change)
// If saturationBoost > 1, color is pushed further from lum (more saturated)
let sr = lum + actualSaturationBoost * (r - lum);
let sg = lum + actualSaturationBoost * (g - lum);
let sb = lum + actualSaturationBoost * (b - lum);
// Clamp saturated values to [0, 1] range before applying contrast
sr = Math.max(0, Math.min(1, sr));
sg = Math.max(0, Math.min(1, sg));
sb = Math.max(0, Math.min(1, sb));
// 2. Apply Contrast Boost
// Adjust contrast using the formula: C_final = factor * (C_intermediate - 0.5) + 0.5
// This formula increases the difference from the midpoint (0.5 gray)
// If contrastBoost = 1, C_final = C_intermediate (no change)
// If contrastBoost > 1, contrast is increased.
let cr = actualContrastBoost * (sr - 0.5) + 0.5;
let cg = actualContrastBoost * (sg - 0.5) + 0.5;
let cb = actualContrastBoost * (sb - 0.5) + 0.5;
// Denormalize (back to [0, 255] range) and clamp the final R, G, B values
data[i] = Math.max(0, Math.min(255, cr * 255));
data[i + 1] = Math.max(0, Math.min(255, cg * 255));
data[i + 2] = Math.max(0, Math.min(255, cb * 255));
}
// Put the modified pixel data back onto the canvas
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 Vibrant Color Pop Filter enhances your images by increasing their color saturation and contrast. This tool is ideal for photographers and graphic designers looking to make photos more visually striking. By adjusting saturation and contrast levels, users can achieve a more vibrant and dynamic appearance for their images, making it useful for social media posts, marketing materials, or artistic projects.