Please bookmark this page to avoid losing your image tool!

Image Pinch 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, centerXStr = "0.5", centerYStr = "0.5", radiusStr = "200", strengthStr = "0.5") {
    // Default values that correspond to the function signature defaults
    const defaultCenterXRel = 0.5;
    const defaultCenterYRel = 0.5;
    const defaultRadius = 200;
    const defaultStrength = 0.5;

    // Parse centerX parameter
    let centerX_rel = parseFloat(centerXStr);
    if (isNaN(centerX_rel)) {
        centerX_rel = defaultCenterXRel;
    }

    // Parse centerY parameter
    let centerY_rel = parseFloat(centerYStr);
    if (isNaN(centerY_rel)) {
        centerY_rel = defaultCenterYRel;
    }

    // Parse radius parameter
    let radius = parseFloat(radiusStr);
    if (isNaN(radius) || radius <= 0) { // If not a number or not positive
        radius = defaultRadius;
    }
    radius = Math.max(1, radius); // Ensure radius is at least 1 pixel

    // Parse strength parameter
    let strength = parseFloat(strengthStr);
    if (isNaN(strength)) {
        strength = defaultStrength;
    }

    // Clamp strength: The distortion factor k = (1 + strength).
    // k must be greater than 0 for Math.pow to work as expected with potentially fractional base.
    // So, strength must be greater than -1.
    if (strength <= -1.0) {
        strength = -0.999; // Use a value very close to -1 to keep k > 0
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

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

    // If the image has no dimensions (e.g., it's not loaded or it's an invalid image),
    // we can't process it. Return an empty (or original-sized but blank) canvas.
    if (width === 0 || height === 0) {
        console.warn("Image has zero width or height. Returning an empty canvas.");
        return canvas;
    }
    
    // Draw the original image onto the canvas. This is our source.
    ctx.drawImage(originalImg, 0, 0, width, height);

    // If strength is 0, there's no distortion effect.
    // Return the canvas with the original image drawn on it.
    if (strength === 0) {
        return canvas;
    }

    const sourceImageData = ctx.getImageData(0, 0, width, height);
    const destImageData = ctx.createImageData(width, height); // Create new ImageData for the destination
    const sourceData = sourceImageData.data;
    const destData = destImageData.data;

    // Absolute coordinates of the pinch/bulge center
    const centerX_abs = centerX_rel * width;
    const centerY_abs = centerY_rel * height;

    // The distortion factor k.
    // If strength > 0 (pinch), k > 1.
    // If strength < 0 (bulge), 0 < k < 1.
    const k = 1.0 + strength;

    for (let y = 0; y < height; y++) { // Iterate over each pixel in the destination image
        for (let x = 0; x < width; x++) {
            const dx = x - centerX_abs; // Horizontal distance of current pixel from center
            const dy = y - centerY_abs; // Vertical distance of current pixel from center
            const distDest = Math.sqrt(dx * dx + dy * dy); // Distance of destination pixel from center

            let srcX, srcY; // Coordinates of the source pixel to sample from

            // If the current pixel is outside the affected radius, or exactly at the center,
            // it remains unchanged (samples from its own position).
            if (distDest >= radius || distDest === 0) {
                srcX = x;
                srcY = y;
            } else {
                const theta = Math.atan2(dy, dx); // Angle of the destination pixel relative to center

                // Normalize the destination distance (0 to 1 within the radius)
                const distDestNorm = distDest / radius;
                
                // Apply the inverse distortion formula to find the normalized source distance:
                // r_src_norm = (r_dest_norm)^(1/k)
                const distSrcNorm = Math.pow(distDestNorm, 1.0 / k);
                
                // Convert normalized source distance back to absolute pixel distance
                const distSrc = distSrcNorm * radius;

                // Calculate source coordinates by applying the new (undistorted) distance at the original angle
                srcX = centerX_abs + distSrc * Math.cos(theta);
                srcY = centerY_abs + distSrc * Math.sin(theta);
            }

            // --- Pixel Sampling (Nearest Neighbor) ---
            // Round source coordinates to the nearest integer
            const iSrcX = Math.round(srcX);
            const iSrcY = Math.round(srcY);

            // Clamp coordinates to be within the image boundaries
            // This prevents trying to read pixel data from outside the image
            const clampedSrcX = Math.max(0, Math.min(width - 1, iSrcX));
            const clampedSrcY = Math.max(0, Math.min(height - 1, iSrcY));

            // Calculate the 1D array index for source and destination pixel data (RGBA format)
            const srcIdx = (clampedSrcY * width + clampedSrcX) * 4;
            const destIdx = (y * width + x) * 4;

            // Copy RGBA components from source to destination
            destData[destIdx]     = sourceData[srcIdx];     // Red
            destData[destIdx + 1] = sourceData[srcIdx + 1]; // Green
            destData[destIdx + 2] = sourceData[srcIdx + 2]; // Blue
            destData[destIdx + 3] = sourceData[srcIdx + 3]; // Alpha
        }
    }

    // Write the modified pixel data from destImageData back onto the canvas
    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 Pinch Filter Application allows users to apply a pinch or bulge effect to images, altering the appearance by distorting parts of the image based on specified parameters. Users can define the center point of the distortion effect, the radius within which the effect will be applied, and the strength of the distortion, enabling fine-tuning for various artistic or correction purposes. This tool is ideal for graphic designers, photographers, and anyone looking to enhance their images or create unique visual effects.

Leave a Reply

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