You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, contrastValue = 1.4, saturationValue = 1.3, vignetteIntensity = 0.6, vignetteSize = 0.7, redChannelMultiplier = 1.1, greenChannelMultiplier = 0.95, blueChannelMultiplier = 1.05) {
// Nested Helper: RGB to HSL
// r, g, b are values from 0 to 255
// h, s, l are values from 0 to 1
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
// Nested Helper: HSL to RGB
// h, s, l are values from 0 to 1
// r, g, b are returned as values from 0 to 255
function hslToRgb(h, s, l) {
let r_out, g_out, b_out;
if (s === 0) {
r_out = g_out = b_out = l; // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r_out = hue2rgb(p, q, h + 1 / 3);
g_out = hue2rgb(p, q, h);
b_out = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r_out * 255), Math.round(g_out * 255), Math.round(b_out * 255)];
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true }); // willReadFrequently for performance
// Use naturalWidth/Height for Image objects to ensure they are loaded.
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
// 1. Draw original image
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 2. Pixel manipulation (Contrast, Saturation, Color Channel adjustments)
if (canvas.width > 0 && canvas.height > 0) {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// a. Contrast
// contrastValue: 1.0 is no change. <1 reduces contrast, >1 increases. 0 is mid-gray.
const safeContrast = Math.max(0, contrastValue);
r = ((r / 255 - 0.5) * safeContrast + 0.5) * 255;
g = ((g / 255 - 0.5) * safeContrast + 0.5) * 255;
b = ((b / 255 - 0.5) * safeContrast + 0.5) * 255;
// Clamp values after contrast before HSL conversion
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// b. Saturation
// saturationValue: 1.0 is no change. 0.0 is grayscale. >1 increases saturation.
if (saturationValue !== 1.0) {
let [h, s, l] = rgbToHsl(r, g, b);
s *= saturationValue;
s = Math.max(0, Math.min(1, s)); // Clamp s: 0 to 1
[r, g, b] = hslToRgb(h, s, l);
}
// c. Channel Multipliers for color tinting
// Multipliers around 1.0. E.g., 1.1 = 10% boost. 0.9 = 10% reduction.
r *= redChannelMultiplier;
g *= greenChannelMultiplier;
b *= blueChannelMultiplier;
// Clamp final RGB values to 0-255 range
data[i] = Math.max(0, Math.min(255, Math.round(r)));
data[i + 1] = Math.max(0, Math.min(255, Math.round(g)));
data[i + 2] = Math.max(0, Math.min(255, Math.round(b)));
}
ctx.putImageData(imageData, 0, 0);
}
// 3. Vignetting
// vignetteIntensity: 0.0 (no vignette) to 1.0 (fully opaque vignette color).
// vignetteSize: 0.0 (vignette starts at center) to 1.0+ (vignette starts at/beyond image edge).
// A typical vignetteSize is 0.5-0.8.
if (vignetteIntensity > 0 && canvas.width > 0 && canvas.height > 0) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// r_clear_end: Radius where the vignette effect begins (center is fully clear up to this radius).
// This radius is relative to the smaller dimension of the image, scaled by vignetteSize.
const r_clear_end = Math.max(0, vignetteSize * Math.min(centerX, centerY));
// r_full_dark: Radius where the vignette effect is at its full intensity (outer radius of the gradient).
// This extends to the farthest corners of the image.
const r_full_dark = Math.sqrt(centerX * centerX + centerY * centerY);
if (r_clear_end < r_full_dark) { // Ensure inner radius is less than outer radius for a valid gradient
const radialGradient = ctx.createRadialGradient(centerX, centerY, r_clear_end, centerX, centerY, r_full_dark);
radialGradient.addColorStop(0, 'rgba(0,0,0,0)'); // Transparent at the start of vignette effect
radialGradient.addColorStop(1, `rgba(0,0,0,${vignetteIntensity})`); // Vignette color at full intensity
ctx.fillStyle = radialGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
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 Toy Camera Effect Enhancer is a web-based tool designed to apply distinctive toy camera effects to your images. By adjusting various parameters such as contrast, saturation, and color channels, users can enhance their images with vibrant colors and rich tones. Additionally, this tool allows for the application of vignetting effects, which creates a smooth transition around the edges of the image, drawing the viewer’s eye towards the center. This tool is perfect for photographers, social media enthusiasts, and anyone looking to add a creative touch to their images, making it ideal for enhancing personal photos, creating artistic visuals, or simply exploring different styles of image editing.