Please bookmark this page to avoid losing your image tool!

Image Gravitational Lens 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, lensCenterXRatio = 0.5, lensCenterYRatio = 0.5, lensStrength = 0.3, lensRadiusRatio = 0.4) {
    // Ensure parameters are numbers
    lensCenterXRatio = Number(lensCenterXRatio);
    lensCenterYRatio = Number(lensCenterYRatio);
    lensStrength = Number(lensStrength);
    lensRadiusRatio = Number(lensRadiusRatio);

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

    // Create a canvas to draw the original image and get its pixel data
    // This step is necessary because we need pixel-level access to the original image.
    const inputCanvas = document.createElement('canvas');
    inputCanvas.width = width;
    inputCanvas.height = height;
    const inputCtx = inputCanvas.getContext('2d', { willReadFrequently: true }); // Hint for optimization
    inputCtx.drawImage(originalImg, 0, 0, width, height);
    
    let inputImageData;
    try {
        inputImageData = inputCtx.getImageData(0, 0, width, height);
    } catch (e) {
        console.error("Error getting image data from input canvas. This can happen due to CORS restrictions if the image is from a different origin and the canvas becomes tainted.", e);
        // Fallback: return a new canvas with the original image drawn, if processing fails.
        const fallbackCanvas = document.createElement('canvas');
        fallbackCanvas.width = width;
        fallbackCanvas.height = height;
        const fallbackCtx = fallbackCanvas.getContext('2d');
        fallbackCtx.drawImage(originalImg, 0, 0, width, height);
        return fallbackCanvas;
    }
    const inputData = inputImageData.data;

    // Create the output canvas
    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = width;
    outputCanvas.height = height;
    const outputCtx = outputCanvas.getContext('2d');
    const outputImageData = outputCtx.createImageData(width, height);
    const outputData = outputImageData.data;

    const centerX = width * lensCenterXRatio;
    const centerY = height * lensCenterYRatio;
    
    const minDimension = Math.min(width, height);
    const radius = minDimension * lensRadiusRatio;

    // If radius is 0 or negative, or strength is 0, there's no visual effect.
    // In this case, draw the original image onto the output canvas and return it.
    if (radius <= 0 || lensStrength === 0) {
        outputCtx.drawImage(originalImg, 0, 0, width, height);
        return outputCanvas;
    }
    
    // Power for the falloff of the lens effect.
    // 1.0 means linear falloff, 2.0 means quadratic (effect more concentrated at center).
    const pullEffectFalloffPower = 1.0; 

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const dx = x - centerX; // Vector from lens center to current pixel
            const dy = y - centerY;
            const distanceSq = dx * dx + dy * dy; // Squared distance

            let sourceX = x; // Coords of the pixel to sample from the original image
            let sourceY = y;

            // Check if the current pixel (x,y) is within the lens's radius of influence
            if (distanceSq < radius * radius) {
                const distance = Math.sqrt(distanceSq); // Actual distance

                if (distance === 0) { 
                    // If at the exact center of the lens, sample from the center.
                    sourceX = centerX;
                    sourceY = centerY;
                } else {
                    // Normalized distance from center (0.0 at center, 1.0 at radius edge)
                    const normDist = distance / radius; 
                    
                    // Calculate the "pull" amount.
                    // This is strongest at the center (max `lensStrength`) and zero at the edge of the radius.
                    // A positive `lensStrength` "pulls" the image, resembling gravitational lensing (pinch).
                    // A negative `lensStrength` "pushes" (bulge/magnification).
                    const pullAmount = lensStrength * Math.pow(1.0 - normDist, pullEffectFalloffPower);
                    
                    // Calculate the scaling factor for the radial vector (dx, dy).
                    // A scaleFactor > 1.0 means sampling from further out from the lens center (pinch effect).
                    // A scaleFactor < 1.0 means sampling from closer to the lens center (bulge effect).
                    const scaleFactor = 1.0 + pullAmount;

                    sourceX = centerX + dx * scaleFactor;
                    sourceY = centerY + dy * scaleFactor;
                }
            }

            // Determine the source pixel using nearest neighbor sampling.
            // Clamp coordinates to be within the image boundaries.
            const sx = Math.max(0, Math.min(width - 1, Math.round(sourceX)));
            const sy = Math.max(0, Math.min(height - 1, Math.round(sourceY)));

            const inputIndex = (sy * width + sx) * 4;   // Index for inputImageData array
            const outputIndex = (y * width + x) * 4; // Index for outputImageData array

            // Copy pixel data (R, G, B, A) from source to target
            outputData[outputIndex]     = inputData[inputIndex];
            outputData[outputIndex + 1] = inputData[inputIndex + 1];
            outputData[outputIndex + 2] = inputData[inputIndex + 2];
            outputData[outputIndex + 3] = inputData[inputIndex + 3];
        }
    }

    // Write the modified pixel data to the output canvas
    outputCtx.putImageData(outputImageData, 0, 0);
    return outputCanvas;
}

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 Gravitational Lens Filter Effect Tool allows users to apply a gravitational lensing effect to images. This tool can simulate the visual distortion seen in astronomical images, where gravity alters the path of light. By adjusting parameters such as the lens center, strength, and radius, users can create unique artistic effects for photography, graphic design, or educational purposes. It’s useful for artists looking to add depth to their images or for anyone attempting to create visually striking alterations to their pictures.

Leave a Reply

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