You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, intensity = 1.0) {
let effectIntensity = parseFloat(intensity);
if (isNaN(effectIntensity)) effectIntensity = 1.0;
effectIntensity = Math.max(0, effectIntensity);
const canvas = document.createElement('canvas');
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
const ctx = canvas.getContext('2d');
// Draw original image onto canvas
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Give up silently (or return as-is) if canvas has been tainted (CORS issue)
let imgData;
try {
imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (e) {
console.error("CORS issue: Cannot read image data.", e);
return canvas;
}
const data = imgData.data;
const maxShift = 40 * effectIntensity;
// Use Typed Arrays to avoid garbage collection pressure during the tight loop
const hsl = new Float32Array(3);
const rgb = new Float32Array(3);
// Helper functions for color spaces
function rgbToHsl(r, g, b, out) {
let r1 = r / 255, g1 = g / 255, b1 = b / 255;
let max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
let d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r1: h = (g1 - b1) / d + (g1 < b1 ? 6 : 0); break;
case g1: h = (b1 - r1) / d + 2; break;
case b1: h = (r1 - g1) / d + 4; break;
}
h /= 6;
}
out[0] = h * 360;
out[1] = s;
out[2] = l;
}
function 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;
}
function hslToRgb(h, s, l, out) {
h /= 360;
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
let q = l < 0.5 ? l * (1 + s) : l + s - l * s;
let p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
out[0] = Math.round(r * 255);
out[1] = Math.round(g * 255);
out[2] = Math.round(b * 255);
}
// Process every pixel
for (let i = 0; i < data.length; i += 4) {
// Skip fully transparent pixels
if (data[i + 3] === 0) continue;
let r = data[i];
let g = data[i+1];
let b = data[i+2];
// 1. Hue Warp & Saturation & Contrast adjustments
rgbToHsl(r, g, b, hsl);
let h = hsl[0];
let s = hsl[1];
let l = hsl[2];
// We use a sine wave mapping to smoothly warp hues towards Orange (30deg) or Cyan (210deg)
// without causing hard angular breaks in the colors.
let shift = -Math.sin((h - 30) * Math.PI / 90) * maxShift;
h += shift;
// Wrap Hue values ensuring they are within [0; 360]
if (h < 0) h += 360;
if (h >= 360) h -= 360;
// Boost saturation subtly to aid the cinematic "pop"
s = Math.min(1.0, s * (1 + 0.3 * effectIntensity));
// Soft S-curve contrast boost on lightness
l = l + (l - 0.5) * 0.1 * effectIntensity;
l = Math.max(0, Math.min(1, l));
// 2. Convert mapped HSL back to RGB for final split-tone processing
hslToRgb(h, s, l, rgb);
r = rgb[0];
g = rgb[1];
b = rgb[2];
// 3. Cinematic Split Toning (Shadows -> Cyan, Highlights -> Orange)
// Calculating perceived image luminescence (0-255)
let y = 0.299 * r + 0.587 * g + 0.114 * b;
let wS = 0;
let wH = 0;
// Utilize bell-shaped logic mathematically so pure whites remain white,
// pure blacks remain black, and the tints peak in the mid-shadows / mid-highlights.
if (y < 128) {
wS = Math.sin((1 - y / 128) * Math.PI);
} else {
wH = Math.sin(((y - 128) / 127) * Math.PI);
}
// Apply additive split-tone colors proportionally
r = r + wH * 40 * effectIntensity - wS * 30 * effectIntensity;
g = g + wH * 15 * effectIntensity + wS * 20 * effectIntensity;
b = b - wH * 40 * effectIntensity + wS * 40 * effectIntensity;
// Apply clamping and map back to byte array
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));
}
ctx.putImageData(imgData, 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 Cyan and Orange Image Effect Generator applies a cinematic split-toning filter to your images. By manipulating hue, saturation, and contrast, the tool shifts shadows toward cyan tones and highlights toward orange tones to create a professional, stylized look. It includes an intensity control to adjust the strength of the color warp and split-toning effect. This tool is ideal for photographers and content creators looking to give their photos a dramatic, high-contrast, or ‘teal and orange’ cinematic aesthetic for social media, digital art, or film-inspired projects.