Please bookmark this page to avoid losing your image tool!

Image Molten Glass Filter Effect 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, displacementAmount = 20, noiseScaleInput = 50) {

    // Parameter sanitization
    // Ensure noiseScale is at least 1; otherwise, grid calculations can be problematic.
    const noiseScale = Math.max(1, noiseScaleInput); 
    const W = originalImg.width;
    const H = originalImg.height;

    // Handle cases where the image might not be loaded or has zero dimensions
    if (W === 0 || H === 0) {
        console.warn("Original image has zero width or height. Returning a 1x1 transparent canvas.");
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = 1;
        emptyCanvas.height = 1;
        const emptyCtx = emptyCanvas.getContext('2d');
        if (emptyCtx) {
             emptyCtx.fillStyle = 'rgba(0,0,0,0)'; // Transparent
             emptyCtx.fillRect(0,0,1,1);
        }
        return emptyCanvas;
    }

    const canvas = document.createElement('canvas');
    canvas.width = W;
    canvas.height = H;
    const ctx = canvas.getContext('2d');

    // Should not happen for '2d', but good practice to check
    if (!ctx) {
        console.error("Could not get 2D context from canvas. Returning an empty canvas.");
        return canvas; 
    }

    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0);
    
    // Get image data
    let originalImageData;
    try {
        originalImageData = ctx.getImageData(0, 0, W, H);
    } catch (e) {
        // This can happen due to tainted canvas if image is cross-origin and CORS isn't set up
        console.error("Could not get ImageData, possibly due to CORS policy. Error:", e);
        // Return the canvas with the original image drawn, without the effect
        return canvas;
    }
    
    const outputImageData = ctx.createImageData(W, H);
    
    const originalData = originalImageData.data;
    const outputData = outputImageData.data;

    // Helper function for linear interpolation
    function lerp(a, b, t) {
        return a * (1 - t) + b * t;
    }

    // Helper function for bilinear interpolation from a grid
    // gx, gy are fractional coordinates in the grid
    function interpolateFromGrid(grid, gx, gy) {
        const x_floor = Math.floor(gx);
        const y_floor = Math.floor(gy);
        const x_frac = gx - x_floor;
        const y_frac = gy - y_floor;

        const gridActualHeight = grid.length;
        const gridActualWidth = grid[0].length;

        // Coordinates of the four grid points surrounding (gx, gy)
        // These indices are guaranteed to be within the grid dimensions
        // due to how gridW/gridH are calculated and how gx/gy relate to image W/H & noiseScale
        const x0 = x_floor;
        const x1 = x_floor + 1;
        const y0 = y_floor;
        const y1 = y_floor + 1;
        
        // Fetch values from the grid, ensuring x1/y1 don't exceed grid boundaries
        // (they shouldn't if grid size calculation is correct, but this is safer)
        const p00 = grid[y0][x0];
        const p10 = grid[y0][Math.min(x1, gridActualWidth - 1)];
        const p01 = grid[Math.min(y1, gridActualHeight - 1)][x0];
        const p11 = grid[Math.min(y1, gridActualHeight - 1)][Math.min(x1, gridActualWidth - 1)];
        
        const topInterpolation = lerp(p00, p10, x_frac);
        const bottomInterpolation = lerp(p01, p11, x_frac);
        
        return lerp(topInterpolation, bottomInterpolation, y_frac);
    }

    // Calculate dimensions of the noise grid
    // Add 1 to ensure there's always a grid cell to interpolate from, even at edges.
    const gridW = Math.ceil(W / noiseScale) + 1;
    const gridH = Math.ceil(H / noiseScale) + 1;

    // Create and populate displacement grids for X and Y offsets
    const gridDx = Array(gridH).fill(null).map(() => Array(gridW).fill(0));
    const gridDy = Array(gridH).fill(null).map(() => Array(gridW).fill(0));

    for (let j = 0; j < gridH; j++) {
        for (let i = 0; i < gridW; i++) {
            // Random values between -displacementAmount and +displacementAmount
            gridDx[j][i] = (Math.random() - 0.5) * 2 * displacementAmount;
            gridDy[j][i] = (Math.random() - 0.5) * 2 * displacementAmount;
        }
    }

    // Main loop to process each pixel
    for (let y = 0; y < H; y++) {
        for (let x = 0; x < W; x++) {
            // Calculate fractional coordinates in the noise grid
            const gx = x / noiseScale;
            const gy = y / noiseScale;

            // Interpolate displacement values from the grids
            const finalDx = interpolateFromGrid(gridDx, gx, gy);
            const finalDy = interpolateFromGrid(gridDy, gx, gy);

            // Calculate source pixel coordinates after displacement
            const sourceX = x + finalDx;
            const sourceY = y + finalDy;

            // Clamp source coordinates to be within image boundaries and round to nearest integer
            const clampedSourceX = Math.max(0, Math.min(W - 1, Math.round(sourceX)));
            const clampedSourceY = Math.max(0, Math.min(H - 1, Math.round(sourceY)));

            // Calculate array indices for source and destination pixels
            const sourceIndex = (clampedSourceY * W + clampedSourceX) * 4;
            const destIndex = (y * W + x) * 4;

            // Copy pixel data from source (original) to destination (output)
            outputData[destIndex]     = originalData[sourceIndex];     // R
            outputData[destIndex + 1] = originalData[sourceIndex + 1]; // G
            outputData[destIndex + 2] = originalData[sourceIndex + 2]; // B
            outputData[destIndex + 3] = originalData[sourceIndex + 3]; // A
        }
    }

    // Put the modified pixel data back onto the canvas
    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 Molten Glass Filter Effect Application is a tool that allows users to apply a unique molten glass effect to their images. By adjusting parameters such as displacement amount and noise scale, users can create visually striking effects that mimic the look of molten glass. This tool is ideal for artists, graphic designers, and photographers looking to enhance their images with abstract and textured effects, making it suitable for creative projects, social media graphics, and personalized artwork.

Leave a Reply

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