Please bookmark this page to avoid losing your image tool!

Image Sparkle Filter Application

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
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!

Description

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.

Leave a Reply

Your email address will not be published. Required fields are marked *