Please bookmark this page to avoid losing your image tool!

Photo Glowing Skeleton Filter Effect Tool

(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, glowColor = '#00ffcc', glowIntensity = 10, backgroundDarkness = 90, edgeSmoothing = 2, edgeSensitivity = 20) {
    // Parameter normalization
    glowIntensity = Math.abs(Number(glowIntensity));
    if (isNaN(glowIntensity)) glowIntensity = 10;

    backgroundDarkness = Math.min(100, Math.max(0, Number(backgroundDarkness)));
    if (isNaN(backgroundDarkness)) backgroundDarkness = 90;

    edgeSmoothing = Math.abs(Number(edgeSmoothing));
    if (isNaN(edgeSmoothing)) edgeSmoothing = 2;

    edgeSensitivity = Math.abs(Number(edgeSensitivity));
    if (isNaN(edgeSensitivity)) edgeSensitivity = 20;

    const width = originalImg.width || originalImg.naturalWidth;
    const height = originalImg.height || originalImg.naturalHeight;

    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Parse the requested neon glow color into RGB using canvas fillStyle
    ctx.fillStyle = glowColor;
    ctx.fillRect(0, 0, 1, 1);
    const colorData = ctx.getImageData(0, 0, 1, 1).data;
    const rC = colorData[0], gC = colorData[1], bC = colorData[2];

    ctx.clearRect(0, 0, width, height);

    // Render the original image temporarily with blur to suppress noise/texture and extract structural "skeleton" lines
    ctx.filter = `blur(${edgeSmoothing}px)`;
    ctx.drawImage(originalImg, 0, 0, width, height);
    ctx.filter = 'none';

    // Retrieve pixel data for Sobel Edge Detection processing
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;
    
    // Create a grayscale channel
    const gray = new Float32Array(width * height);
    for (let i = 0; i < data.length; i += 4) {
        gray[i / 4] = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
    }

    const edgeData = new Uint8ClampedArray(width * height * 4);

    // Sobel operator math
    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            const i = y * width + x;
            
            // Map surrounding pixels
            const i00 = i - width - 1, i01 = i - width, i02 = i - width + 1;
            const i10 = i - 1,                          i12 = i + 1;
            const i20 = i + width - 1, i21 = i + width, i22 = i + width + 1;

            const gx = -gray[i00] + gray[i02]
                       -2 * gray[i10] + 2 * gray[i12]
                       -gray[i20] + gray[i22];

            const gy = -gray[i00] - 2 * gray[i01] - gray[i02]
                       +gray[i20] + 2 * gray[i21] + gray[i22];

            const mag = Math.sqrt(gx * gx + gy * gy);

            if (mag > edgeSensitivity) {
                // Apply color and create a gradual anti-aliased edge based on gradient intensity
                const alpha = Math.min(255, (mag - edgeSensitivity) * 1.5);
                const outIdx = i * 4;
                edgeData[outIdx]     = rC;
                edgeData[outIdx + 1] = gC;
                edgeData[outIdx + 2] = bC;
                edgeData[outIdx + 3] = alpha;
            }
        }
    }

    // Convert edges back into canvas standard element
    const edgeCanvas = document.createElement('canvas');
    edgeCanvas.width = width;
    edgeCanvas.height = height;
    const edgeCtx = edgeCanvas.getContext('2d');
    edgeCtx.putImageData(new ImageData(edgeData, width, height), 0, 0);

    const finalCanvas = document.createElement('canvas');
    finalCanvas.width = width;
    finalCanvas.height = height;
    const fCtx = finalCanvas.getContext('2d');

    // 1. Render base context (keep original image crisp but dark for the dramatic neon filter background context)
    fCtx.drawImage(originalImg, 0, 0, width, height);
    fCtx.fillStyle = `rgba(0, 0, 0, ${backgroundDarkness / 100})`;
    fCtx.fillRect(0, 0, width, height);

    // 2. Composite Glowing Overlays
    // Using screen blend mode creates an authentic illuminated/neon effect
    fCtx.globalCompositeOperation = 'screen';

    if (glowIntensity > 0) {
        // Broad scattered ambient outer-glow
        fCtx.filter = `blur(${glowIntensity * 1.5}px)`;
        fCtx.globalAlpha = 0.5;
        fCtx.drawImage(edgeCanvas, 0, 0);

        // Core dense inner-glow
        fCtx.filter = `blur(${glowIntensity * 0.5}px)`;
        fCtx.globalAlpha = 0.8;
        fCtx.drawImage(edgeCanvas, 0, 0);
    }

    // Standard structural line rendered crisply on top 
    fCtx.filter = 'none';
    fCtx.globalAlpha = 1.0;
    fCtx.drawImage(edgeCanvas, 0, 0);

    return finalCanvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Photo Glowing Skeleton Filter Effect Tool applies a stylized neon edge detection effect to your images. By using Sobel edge detection, the tool extracts the structural outlines of a photo and transforms them into a glowing ‘skeleton’ against a darkened background. Users can customize the appearance by adjusting the glow color, intensity, background darkness, and edge sensitivity. This tool is ideal for creating dramatic social media graphics, artistic portraits, cyberpunk-style visuals, or unique digital art assets.

Leave a Reply

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