Please bookmark this page to avoid losing your image tool!

Image Fisheye Lens Effect Creator

(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, strength = 1.5) {
    // 1. Parameter validation: Ensure strength is >= 1 for a fisheye (barrel) effect.
    // A strength of 1 means no distortion. Values less than 1 would create a pincushion effect.
    if (strength < 1) {
        strength = 1;
    }

    // The distortion exponent is the inverse of the strength.
    // An exponent < 1 is needed for the pow() function to create a barrel distortion.
    const distortion = 1 / strength;

    // 2. Canvas setup
    const {
        width,
        height
    } = originalImg;
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    // Use { willReadFrequently: true } for potential performance gains.
    const ctx = canvas.getContext('2d', {
        willReadFrequently: true
    });

    // 3. Prepare source pixel data
    // Draw the image onto a temporary hidden canvas to access its pixel data easily.
    const sourceCanvas = document.createElement('canvas');
    sourceCanvas.width = width;
    sourceCanvas.height = height;
    const sourceCtx = sourceCanvas.getContext('2d', {
        willReadFrequently: true
    });
    sourceCtx.drawImage(originalImg, 0, 0, width, height);
    const sourceImageData = sourceCtx.getImageData(0, 0, width, height);
    const sourcePixels = sourceImageData.data;

    // 4. Prepare destination pixel data
    const destImageData = ctx.createImageData(width, height);
    const destPixels = destImageData.data;

    // 5. Calculate transformation constants
    const centerX = width / 2;
    const centerY = height / 2;
    // The maximum radius is the distance from the center to a corner,
    // ensuring the effect covers the entire image area.
    const maxRadius = Math.sqrt(centerX * centerX + centerY * centerY);

    // 6. Main loop: Iterate through each pixel of the destination canvas
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            // For each destination pixel (x, y), we will find which source pixel (sx, sy) to sample.
            // This is called inverse mapping and prevents gaps or overlaps in the destination image.

            // Convert the current pixel's (x, y) to a vector from the image center
            const dx = x - centerX;
            const dy = y - centerY;

            // Calculate the distance and angle of the destination pixel from the center
            const dist = Math.sqrt(dx * dx + dy * dy);
            const angle = Math.atan2(dy, dx);

            // Normalize the distance to a value between 0 (center) and 1 (corner)
            const normalizedDist = dist / maxRadius;

            // Apply the distortion function to find the corresponding distance in the source image.
            // For a fisheye effect, we want to sample from a source pixel that is further
            // away from the center than the destination pixel is.
            // The pow() function with an exponent < 1 achieves this, "bulging" the image outwards.
            const sourceNormalizedDist = Math.pow(normalizedDist, distortion);

            // Convert the distorted normalized distance back to an absolute pixel distance in the source image
            const sourceDist = sourceNormalizedDist * maxRadius;

            // Calculate the source pixel coordinates (sx, sy) to sample from
            const sx = centerX + sourceDist * Math.cos(angle);
            const sy = centerY + sourceDist * Math.sin(angle);

            // To make the effect look "really good", we use bilinear interpolation.
            // This smooths the result by averaging the colors of the 4 pixels surrounding the target (sx, sy).
            const x0 = Math.floor(sx);
            const y0 = Math.floor(sy);
            const x1 = x0 + 1;
            const y1 = y0 + 1;

            const destOffset = (y * width + x) * 4;

            // Check if the 4-pixel square for interpolation is within the image bounds
            if (x0 >= 0 && x1 < width && y0 >= 0 && y1 < height) {
                const xFrac = sx - x0;
                const yFrac = sy - y0;
                const xFracInv = 1 - xFrac;
                const yFracInv = 1 - yFrac;

                // Get the indices of the 4 neighboring source pixels
                const p00_idx = (y0 * width + x0) * 4;
                const p10_idx = (y0 * width + x1) * 4;
                const p01_idx = (y1 * width + x0) * 4;
                const p11_idx = (y1 * width + x1) * 4;

                // Bilinearly interpolate each color channel (R, G, B, A)
                for (let c = 0; c < 4; c++) {
                    const p00 = sourcePixels[p00_idx + c];
                    const p10 = sourcePixels[p10_idx + c];
                    const p01 = sourcePixels[p01_idx + c];
                    const p11 = sourcePixels[p11_idx + c];

                    const val = p00 * xFracInv * yFracInv +
                        p10 * xFrac * yFracInv +
                        p01 * xFracInv * yFrac +
                        p11 * xFrac * yFrac;

                    destPixels[destOffset + c] = val;
                }
            } else {
                // If the source coordinates are out of bounds, make the pixel transparent black.
                // This creates the realistic circular cropped effect of a real fisheye lens.
                destPixels[destOffset] = 0; // R
                destPixels[destOffset + 1] = 0; // G
                destPixels[destOffset + 2] = 0; // B
                destPixels[destOffset + 3] = 0; // A
            }
        }
    }

    // 7. Put the processed pixel data onto the canvas and return it
    ctx.putImageData(destImageData, 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 Fisheye Lens Effect Creator is a web tool that allows users to apply a fisheye distortion effect to their images. With adjustable strength settings, users can create dramatic visual transformations that simulate the look of a fisheye lens, making the image appear bulged or spherical. This tool is useful for enhancing photographs, creating artistic effects for social media, or simply experimenting with different visual styles in digital artwork.

Leave a Reply

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