Please bookmark this page to avoid losing your image tool!

Image Bulge 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, bulgeFactor = 0.5, centerXPercent = 50, centerYPercent = 50, radiusPercent = 100) {
    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } can be a performance hint for browsers
    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;

    // Handle cases where image might not be loaded or has zero dimensions
    if (width === 0 || height === 0) {
        // Return the empty (0x0) canvas.
        return canvas; 
    }

    // Draw the original image onto the canvas to access its pixel data
    ctx.drawImage(originalImg, 0, 0, width, height);
    const originalImageData = ctx.getImageData(0, 0, width, height);
    const originalData = originalImageData.data;

    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data;

    // Calculate the actual center coordinates in pixels
    const centerX = width * (centerXPercent / 100);
    const centerY = height * (centerYPercent / 100);
    
    let actualRadius;
    if (radiusPercent <= 0) {
        actualRadius = 0; // Results in no bulge effect if radius is zero or negative
    } else {
        // Radius is defined as a percentage of half the smaller image dimension
        actualRadius = (Math.min(width, height) / 2) * (radiusPercent / 100);
    }

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            // Calculate distance of current pixel (x,y) from the bulge center
            const dx = x - centerX;
            const dy = y - centerY;
            const distance = Math.sqrt(dx * dx + dy * dy);

            let sourceX = x;
            let sourceY = y;

            // Apply bulge effect only if the pixel is within the specified radius
            // and the radius itself is positive
            if (actualRadius > 0 && distance < actualRadius) {
                // Normalize distance: 0 at center, 1 at the edge of actualRadius
                const normalizedDistance = distance / actualRadius; 
                
                // bulgeFactor:
                //   Positive values: bulge outwards (pixels sourced from closer to the center).
                //   Negative values: pinch inwards (pixels sourced from further from the center).
                //   0: no change in distance.
                // (1.0 - normalizedDistance) is the strength of the effect, strongest at center.
                const distortionFactor = 1.0 - bulgeFactor * (1.0 - normalizedDistance);
                
                // Calculate the new distance from the center to sample the source pixel
                const newDistance = distance * distortionFactor;

                // Calculate the angle of the current pixel relative to the center
                // Math.atan2(0,0) is 0, which is handled correctly.
                const angle = Math.atan2(dy, dx); 

                // Convert polar coordinates (angle, newDistance) back to Cartesian to find source pixel
                sourceX = centerX + newDistance * Math.cos(angle);
                sourceY = centerY + newDistance * Math.sin(angle);
            }
            // If outside radius (or radius is 0), sourceX and sourceY remain x and y (no effect)


            // --- Pixel Sampling (Nearest Neighbor) ---
            // Round to the nearest integer coordinates for source pixel
            let sxRounded = Math.round(sourceX);
            let syRounded = Math.round(sourceY);

            // Clamp coordinates to be within the image bounds to avoid errors
            sxRounded = Math.max(0, Math.min(width - 1, sxRounded));
            syRounded = Math.max(0, Math.min(height - 1, syRounded));
            
            // Calculate array indices for source and destination pixel data
            // Each pixel is 4 bytes (R, G, B, A)
            const sourceIndex = (syRounded * width + sxRounded) * 4;
            const destIndex = (y * width + x) * 4;

            // Copy pixel data from source to destination
            outputData[destIndex]     = originalData[sourceIndex];     // Red
            outputData[destIndex + 1] = originalData[sourceIndex + 1]; // Green
            outputData[destIndex + 2] = originalData[sourceIndex + 2]; // Blue
            outputData[destIndex + 3] = originalData[sourceIndex + 3]; // Alpha
        }
    }

    // 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 Bulge Filter Application allows users to apply a bulging effect to images. By adjusting parameters such as bulge factor, center coordinates, and radius, users can create distortions that make images appear as if they are being pushed outwards or pulled inwards from a specific point. This tool is useful for creating artistic effects, enhancing visual storytelling in images, and adding unique touches to photographs for personal or commercial use.

Leave a Reply

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