You can edit the below JavaScript code to customize the image tool.
function processImage(
originalImg,
brightnessThreshold = 220,
sparkleChance = 0.005,
baseSparkleSize = 15,
sparkleColorStr = "rgba(255, 255, 240, 0.9)",
numStarPoints = 5,
starSharpness = 0.5, // Ratio of inner to outer radius, e.g., 0.5 means inner radius is half of outer radius
sizeRandomness = 0.5, // Pct variation, e.g., 0.5 means size varies by +/-25% from baseSparkleSize
addGlow = 1, // 0 for no glow, 1 for glow
glowSpread = 10, // Glow blur radius in pixels
glowColorStr = "" // Glow color string. If empty, uses sparkleColorStr
) {
// --- Parameter Sanitization & Setup ---
const saneBrightnessThreshold = Math.max(0, Math.min(255, brightnessThreshold));
const saneSparkleChance = Math.max(0, Math.min(1, sparkleChance));
let saneBaseSparkleSize = Math.max(2, baseSparkleSize); // Min size 2px for a visible sparkle
const saneNumStarPoints = Math.max(3, Math.floor(numStarPoints)); // Min 3 points for a star
const saneStarSharpness = Math.max(0.01, Math.min(0.99, starSharpness));
const saneSizeRandomness = Math.max(0, Math.min(1, sizeRandomness));
const saneAddGlow = (addGlow === 1);
let saneGlowSpread = Math.max(0, glowSpread);
if (!saneAddGlow) {
saneGlowSpread = 0; // No spread if glow is disabled
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true }); // willReadFrequently for getImageData performance
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
if (imgWidth === 0 || imgHeight === 0) {
console.warn("Image has zero dimensions. Returning an empty canvas.");
canvas.width = 0;
canvas.height = 0;
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
// --- Draw Original Image ---
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
// --- Get Image Data for Analysis ---
// This is done once, and subsequent drawing operations happen on top of the current canvas content.
const imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
const data = imageData.data;
// --- Helper Function to Draw a Star ---
// This function is defined within processImage to have access to its scope (ctx, sanitized parameters etc.)
function _drawStarShape(cx, cy, currentSize, color, points, sharpness, useGlow, currentGlowSpread, gColor) {
const outerRadius = currentSize / 2;
const innerRadius = outerRadius * sharpness;
// Set up glow properties for this star
if (useGlow && currentGlowSpread > 0) {
ctx.shadowColor = (gColor && gColor !== "") ? gColor : color;
ctx.shadowBlur = currentGlowSpread;
} else {
// Reset, as canvas context state is persistent
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
}
ctx.beginPath();
let rotation = -Math.PI / 2; // Start angle: points upwards
const angleStep = Math.PI / points;
// First outer point
ctx.moveTo(cx + Math.cos(rotation) * outerRadius, cy + Math.sin(rotation) * outerRadius);
for (let i = 0; i < points; i++) {
rotation += angleStep; // Rotate to inner point vertex
ctx.lineTo(cx + Math.cos(rotation) * innerRadius, cy + Math.sin(rotation) * innerRadius);
rotation += angleStep; // Rotate to next outer point vertex
ctx.lineTo(cx + Math.cos(rotation) * outerRadius, cy + Math.sin(rotation) * outerRadius);
}
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
// Reset shadow after drawing to prevent affecting other canvas operations outside this function or loop.
// This is important if this star had glow and next operations should not.
// Though, if all sparkles have same glow settings, this could be optimized.
// Safety dictates resetting it here.
if (useGlow && currentGlowSpread > 0) {
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
}
}
// --- Pixel Iteration and Sparkle Drawing ---
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// data[i+3] is alpha, not typically used for brightness calculation.
const brightness = (r + g + b) / 3; // Simple average brightness
if (brightness > saneBrightnessThreshold) {
if (Math.random() < saneSparkleChance) {
const currentX = (i / 4) % imgWidth;
const currentY = Math.floor((i / 4) / imgWidth);
// Calculate randomized sparkle size
// Multiplier ranges from (1 - saneSizeRandomness/2) to (1 + saneSizeRandomness/2)
const sizeMultiplier = (1 - saneSizeRandomness / 2) + (Math.random() * saneSizeRandomness);
const currentSparkleSize = Math.max(1, saneBaseSparkleSize * sizeMultiplier);
// Add a tiny random offset to sparkle position to break up grid patterns
// Offset is proportional to sparkle size to maintain visual balance
const posOffsetX = (Math.random() - 0.5) * (currentSparkleSize / 4);
const posOffsetY = (Math.random() - 0.5) * (currentSparkleSize / 4);
_drawStarShape(
currentX + posOffsetX,
currentY + posOffsetY,
currentSparkleSize,
sparkleColorStr, // Assumed to be a valid CSS color string
saneNumStarPoints,
saneStarSharpness,
saneAddGlow,
saneGlowSpread, // Actual glow spread for this sparkle
glowColorStr // Assumed to be a valid CSS color string (or empty)
);
}
}
}
// Final general reset of shadow properties just in case, before returning the canvas
// This ensures the canvas context state is clean if it's used further elsewhere.
ctx.shadowColor = "transparent";
ctx.shadowBlur = 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 Sparkle Filter Application allows users to enhance images by adding visually appealing sparkle effects. Users can customize the brightness threshold, sparkle size, color, and glow effects, enabling them to create images with unique and eye-catching aesthetic qualities. This tool can be used for various purposes, including enhancing personal photos, creating eye-catching graphics for social media, and adding a magical touch to artistic projects.