You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, opacity = 0.5, direction = "horizontal") {
// Helper function to convert HSL to RGB
// h: 0-360 (degrees), s: 0-1 (saturation), l: 0-1 (lightness)
// returns [r, g, b] where each component is 0-255
const _hslToRgbInternal = (h, s, l) => {
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic (grey)
} else {
const hueToRgbPrime = (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;
const hNormalized = h / 360; // Normalize h to 0-1 range
r = hueToRgbPrime(p, q, hNormalized + 1 / 3);
g = hueToRgbPrime(p, q, hNormalized);
b = hueToRgbPrime(p, q, hNormalized - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
};
// --- Parameter Sanitization ---
let currentOpacity = Number(opacity);
// If opacity is not a valid number (e.g., undefined, "abc"), set to default.
if (isNaN(currentOpacity)) {
currentOpacity = 0.5;
}
// Clamp opacity to the valid range [0, 1].
currentOpacity = Math.max(0, Math.min(1, currentOpacity));
let currentDirection = String(direction).toLowerCase();
// If direction is not 'vertical' or 'horizontal', set to default.
if (currentDirection !== "vertical" && currentDirection !== "horizontal") {
currentDirection = "horizontal";
}
// --- Canvas Setup ---
const canvas = document.createElement('canvas');
// Get 2D rendering context.
// { willReadFrequently: true } is a hint for performance optimization with frequent pixel data access.
const ctx = canvas.getContext('2d', { willReadFrequently: true });
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
// Check if the image is loaded and has valid dimensions.
if (!imgWidth || !imgHeight) {
// Fallback for unloaded or zero-size image: return a small canvas with an error message.
// Ideally, the calling environment ensures the image is loaded.
canvas.width = 200; // Arbitrary small size
canvas.height = 50;
ctx.fillStyle = "rgb(230,230,230)"; // Light grey background
ctx.fillRect(0,0,canvas.width, canvas.height);
ctx.font = "12px Arial";
ctx.fillStyle = "black";
ctx.textAlign = "center";
ctx.fillText("Error: Image not loaded or invalid.", canvas.width/2, canvas.height/2 + 4);
console.warn("[Image Rainbow Filter] processImage: Original image has zero width/height or is not loaded.");
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// Draw the original image onto the canvas.
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
// If opacity is 0, the filter has no visible effect, so return the canvas with the original image.
if (currentOpacity === 0) {
return canvas;
}
// Get image data for pixel manipulation.
const imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
const data = imageData.data; // This is a Uint8ClampedArray: [R,G,B,A, R,G,B,A, ...]
// --- Apply Rainbow Filter ---
if (currentDirection === "horizontal") {
for (let x = 0; x < imgWidth; x++) {
// Calculate normalized position (0 for first pixel column, 1 for last).
// Handles single-pixel width case to avoid division by zero.
const normalizedPos = (imgWidth === 1) ? 0 : x / (imgWidth - 1);
const hue = normalizedPos * 360; // Hue cycles from 0 to 360 degrees.
// Get the pure rainbow color for this hue (full saturation, medium lightness).
const [r_h, g_h, b_h] = _hslToRgbInternal(hue, 1.0, 0.5);
for (let y = 0; y < imgHeight; y++) {
const idx = (y * imgWidth + x) * 4; // Calculate index for the current pixel.
const r_o = data[idx]; // Original red component.
const g_o = data[idx + 1]; // Original green component.
const b_o = data[idx + 2]; // Original blue component.
// Blend original pixel color with the rainbow color using the specified opacity.
data[idx] = Math.round(r_o * (1 - currentOpacity) + r_h * currentOpacity);
data[idx + 1] = Math.round(g_o * (1 - currentOpacity) + g_h * currentOpacity);
data[idx + 2] = Math.round(b_o * (1 - currentOpacity) + b_h * currentOpacity);
// data[idx + 3] (alpha channel) remains unchanged to preserve original transparency.
}
}
} else { // Vertical direction
for (let y = 0; y < imgHeight; y++) {
const normalizedPos = (imgHeight === 1) ? 0 : y / (imgHeight - 1);
const hue = normalizedPos * 360;
const [r_h, g_h, b_h] = _hslToRgbInternal(hue, 1.0, 0.5);
for (let x = 0; x < imgWidth; x++) {
const idx = (y * imgWidth + x) * 4;
const r_o = data[idx];
const g_o = data[idx + 1];
const b_o = data[idx + 2];
data[idx] = Math.round(r_o * (1 - currentOpacity) + r_h * currentOpacity);
data[idx + 1] = Math.round(g_o * (1 - currentOpacity) + g_h * currentOpacity);
data[idx + 2] = Math.round(b_o * (1 - currentOpacity) + b_h * currentOpacity);
}
}
}
// 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 Rainbow Filter Application allows users to apply a vibrant rainbow filter effect to their images. By adjusting the parameters, users can control the opacity and direction of the filter, giving them the ability to enhance their images with colorful gradients. This tool is useful for artists, graphic designers, and anyone looking to add a creative touch to their photos or digital artwork. Whether for social media posts, personal projects, or professional presentations, this application enhances visual appeal with a dynamic color overlay.