Please bookmark this page to avoid losing your image tool!

Image Flames 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, intensity = 0.7, distortionStrength = 15, waviness = 30) {
    const canvas = document.createElement('canvas');
    // {willReadFrequently: true} is a performance hint for the browser
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

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

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, width, height);

    // If image is empty or invalid, return the canvas as is (it might be blank or show a broken image icon)
    if (width === 0 || height === 0) {
        return canvas;
    }
    
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;
    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;

    // Parameter sanitization and defaulting
    let pIntensity = parseFloat(intensity);
    if (isNaN(pIntensity)) pIntensity = 0.7; // Default from signature or if parsing failed
    const effIntensity = Math.max(0, Math.min(1, pIntensity));

    let pDistortionStrength = parseFloat(distortionStrength);
    if (isNaN(pDistortionStrength)) pDistortionStrength = 15;
    const effDistortionStrength = Math.max(0, pDistortionStrength);

    let pWaviness = parseFloat(waviness);
    if (isNaN(pWaviness)) pWaviness = 30;
    const safeWaviness = Math.max(1, pWaviness); // waviness must be at least 1

    // Iterate over each pixel of the destination image
    for (let ty = 0; ty < height; ty++) {
        for (let tx = 0; tx < width; tx++) {
            let srcX_lookup = tx;
            let srcY_lookup = ty;

            if (effDistortionStrength > 0) {
                // Normalized Y (0 at image top, 1 at image bottom)
                // This helps scale effects, making them stronger towards the "base" of the flames (bottom of image)
                const normalizedY = ty / height; // Current version: 0 at top, 1 at bottom
                                                // Alternative: (height - ty) / height; (1 at bottom, 0 at top)
                                                // Lets use (ty/height) because flames tend to dissipate upwards.
                                                // The strength of distortion should reduce towards the top.
                                                // So use (1 - normalizedY) for effects diminishing upwards

                const invNormalizedY = 1.0 - normalizedY; // 1 at top, 0 at bottom. Error here.
                                                         // If flame source is at bottom: (height - ty)/height.
                                                         // Let's properly use: normalized_distance_from_bottom
                const normDistFromBottom = (height - ty) / height; // 1 at bottom, 0 at top.

                // Horizontal displacement (swaying motion)
                // The swaying becomes less pronounced towards the top
                const hDispMagnitude = (effDistortionStrength / 3) * normDistFromBottom;
                const hDisp = hDispMagnitude * 
                              Math.sin(ty / (safeWaviness * 1.2) + 
                                       tx / (safeWaviness * 2.5) +
                                       (ty * tx * 0.00005 / (safeWaviness + 1)) ); // Small chaotic factor
                srcX_lookup = tx + hDisp;

                // Vertical displacement (upward licking motion of flames)
                // Base upward pull, stronger at the bottom, fades towards the top
                const baseUpwardPull = effDistortionStrength * normDistFromBottom * normDistFromBottom; // Quadratic falloff

                // Wavy component for the upward pull effect
                const vWaveMagnitude = effDistortionStrength * 0.6 * normDistFromBottom;
                // Frequency of waves also can change with height (e.g. tighter waves at base)
                const vWaveDynamicWaviness = safeWaviness * (0.5 + normDistFromBottom * 0.5);
                const vWave = vWaveMagnitude * 
                              Math.sin( (tx / safeWaviness) + 
                                        ( (height - ty) / (vWaveDynamicWaviness * 0.8) ) +
                                        (tx * 0.01 / (1 + normDistFromBottom)) // Phase variation
                                      );
                
                // Source Y: current Y + upward pull amount.
                // Positive displacement means sampling from a pixel with a larger Y index (further down in the image source)
                // This creates the visual effect of content moving upwards.
                srcY_lookup = ty + baseUpwardPull + vWave;
            }

            // Clamp source coordinates to be within image bounds
            const clampedSrcX = Math.max(0, Math.min(width - 1, Math.round(srcX_lookup)));
            const clampedSrcY = Math.max(0, Math.min(height - 1, Math.round(srcY_lookup)));

            const srcIdx = (clampedSrcY * width + clampedSrcX) * 4;

            const r_orig = data[srcIdx];
            const g_orig = data[srcIdx + 1];
            const b_orig = data[srcIdx + 2];
            const a_orig = data[srcIdx + 3];

            let r_final = r_orig;
            let g_final = g_orig;
            let b_final = b_orig;

            if (effIntensity > 0) {
                // Flame color transformation
                // These deltas are scaled by effIntensity
                const r_delta = (g_orig * 0.6 + (255 - b_orig) * 0.3);
                const g_reduction_factor = (1 - 0.25 * effIntensity);
                const g_boost_from_r = (r_orig * 0.5);
                const b_reduction_factor = (1 - 0.95 * effIntensity);

                let newR = r_orig + r_delta * effIntensity;
                let newG = g_orig * g_reduction_factor + g_boost_from_r * effIntensity;
                let newB = b_orig * b_reduction_factor;
                
                r_final = Math.max(0, Math.min(255, Math.round(newR)));
                g_final = Math.max(0, Math.min(255, Math.round(newG)));
                b_final = Math.max(0, Math.min(255, Math.round(newB)));
            }
            
            const destIdx = (ty * width + tx) * 4;
            outputData[destIdx]     = r_final;
            outputData[destIdx + 1] = g_final;
            outputData[destIdx + 2] = b_final;
            outputData[destIdx + 3] = a_orig; // Preserve original alpha
        }
    }

    ctx.putImageData(outputImageData, 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!

Description

The Image Flames Filter Application allows users to apply a flame-like distortion effect to their images. By adjusting parameters such as intensity, distortion strength, and waviness, users can create visually striking flame effects that can enhance photos, artistic projects, and digital art. This tool is ideal for graphic designers, digital artists, and anyone looking to add a creative and dynamic touch to their images.

Leave a Reply

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