You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Use naturalWidth/Height for intrinsic image dimensions.
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
// Ensure canvas has valid dimensions.
if (imgWidth === 0 || imgHeight === 0) {
canvas.width = 0;
canvas.height = 0;
console.warn("MysteriousFilter: Input image has zero dimensions.");
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// Draw the original image onto the canvas.
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
let imageData;
try {
// Get pixel data from the canvas.
imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
} catch (e) {
// This can happen due to cross-origin issues (tainted canvas) or other errors.
console.error("MysteriousFilter: Failed to get image data.", e);
// Return the canvas with the original image drawn, effectively bypassing the filter.
return canvas;
}
const data = imageData.data;
const width = canvas.width;
const height = canvas.height;
// Center coordinates for vignette calculation.
// These will be >= 0.5 if width/height >= 1.
const centerX = width / 2;
const centerY = height / 2;
// --- Filter Parameters ---
// These values are chosen to create a "mysterious" look.
// Desaturation: 0 means original color, 1 means full grayscale.
// A value of 0.65 makes the image significantly, but not completely, desaturated.
const desaturationFactor = 0.65;
// Color Tinting & Darkening: Multipliers for R, G, B channels after desaturation.
// Values < 1 generally darken the image.
// The chosen ratios (R:0.6, G:0.7, B:0.95) will produce a cool, slightly bluish tint.
const tintR_factor = 0.6;
const tintG_factor = 0.7;
const tintB_factor = 0.95;
// Vignette: Darkens the edges of the image to draw focus to the center.
const vignetteStrength = 0.9; // How dark the vignette effect is (0 to 1). Higher is darker.
const vignetteStart = 0.15; // Normalized distance from center where vignette starts fading in (0 to 1).
const vignetteEnd = 0.9; // Normalized distance from center where vignette is at full strength (0 to 1).
// Must be > vignetteStart for a gradual fade.
// Iterate over each pixel (each pixel is 4 values in data: R, G, B, A).
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i + 1];
let b = data[i + 2];
// Step 1: Apply Desaturation
// Standard luminosity method for grayscale conversion.
const gray = 0.299 * r + 0.587 * g + 0.114 * b;
// Linearly interpolate between the original color and its grayscale equivalent.
r = r * (1 - desaturationFactor) + gray * desaturationFactor;
g = g * (1 - desaturationFactor) + gray * desaturationFactor;
b = b * (1 - desaturationFactor) + gray * desaturationFactor;
// Step 2: Apply Cool Tint & Darkening
// Multiply color components by tinting factors.
r *= tintR_factor;
g *= tintG_factor;
b *= tintB_factor;
// Step 3: Apply Vignette
// Calculate current pixel's (x, y) coordinates.
const yPx = Math.floor((i / 4) / width);
const xPx = (i / 4) % width;
// Calculate distance from center relative to image dimensions for an elliptical vignette.
const dx = xPx - centerX;
const dy = yPx - centerY;
// normalizedDist = 0 at center, 1 on the ellipse touching image borders, >1 beyond.
// Division by centerX/centerY is safe as width/height are >= 1, so centerX/centerY >= 0.5.
const normalizedDist = Math.sqrt(Math.pow(dx / centerX, 2) + Math.pow(dy / centerY, 2));
let currentVignetteEffect = 0; // Factor for vignette strength (0 to 1)
if (normalizedDist > vignetteStart) {
// Ensure vignetteEnd is greater than vignetteStart to avoid division by zero or negative values.
if (vignetteEnd > vignetteStart) {
// Calculate progression of vignette effect within its defined range.
currentVignetteEffect = (normalizedDist - vignetteStart) / (vignetteEnd - vignetteStart);
} else if (normalizedDist >= vignetteStart) {
// If vignetteEnd <= vignetteStart, apply full effect immediately after vignetteStart.
currentVignetteEffect = 1;
}
// Clamp the effect strength to a maximum of 1 (it can exceed 1 if normalizedDist > vignetteEnd).
// Ensure it's not negative (although with normalizedDist > vignetteStart, it shouldn't be).
currentVignetteEffect = Math.min(1, Math.max(0, currentVignetteEffect));
}
// Reduce brightness based on vignette effect strength.
// A darkeningFactor of 1 means no change, 0 means black.
const darkeningFactor = 1 - currentVignetteEffect * vignetteStrength;
r *= darkeningFactor;
g *= darkeningFactor;
b *= darkeningFactor; // Alpha channel (data[i+3]) is preserved.
// Ensure final color component values remain within the valid [0, 255] range.
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));
}
// Write the modified pixel data back to 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 Mysterious Filter tool allows users to apply a unique filter effect to images, resulting in a visually intriguing and atmospheric appearance. This filter enhances images by desaturating colors, applying a cool tint, and adding a vignette effect to draw focus towards the center. It is ideal for creating artistic modifications to photos that can enhance mood and aesthetic appeal, making it suitable for use in graphic design, social media content creation, and artistic expressions.