Please bookmark this page to avoid losing your image tool!

Image Uncomfortable Guest Remover

(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, guestX = "20%", guestY = "20%", guestWidth = "30%", guestHeight = "60%") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    
    ctx.drawImage(originalImg, 0, 0);

    // Helper to parse percentages or fixed pixel values
    const parseVal = (val, max) => {
        if (typeof val === 'string' && val.endsWith('%')) {
            return (parseFloat(val) / 100) * max;
        }
        return parseFloat(val) || 0;
    };

    const x0 = Math.floor(parseVal(guestX, canvas.width));
    const y0 = Math.floor(parseVal(guestY, canvas.height));
    const w = Math.floor(parseVal(guestWidth, canvas.width));
    const h = Math.floor(parseVal(guestHeight, canvas.height));

    const x1 = Math.min(x0 + w - 1, canvas.width - 1);
    const y1 = Math.min(y0 + h - 1, canvas.height - 1);

    const startX = Math.max(0, x0);
    const startY = Math.max(0, y0);
    const endX = Math.max(0, x1);
    const endY = Math.max(0, y1);

    // If the bounds are invalid, return the unmodified image
    if (endX <= startX || endY <= startY) return canvas;

    const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imgData.data;
    // We keep a clean copy of the original data to reference edge pixels
    const originalData = new Uint8ClampedArray(data);

    const getPixel = (x, y) => {
        // Clamp to edges to prevent out of bounds
        x = Math.max(0, Math.min(canvas.width - 1, x));
        y = Math.max(0, Math.min(canvas.height - 1, y));
        const idx = (y * canvas.width + x) * 4;
        return [originalData[idx], originalData[idx+1], originalData[idx+2], originalData[idx+3]];
    };

    // Replace the bounding box with a content-aware patch (inverse-distance weighted bleed)
    for (let y = startY; y <= endY; y++) {
        for (let x = startX; x <= endX; x++) {
            const dL = x - startX + 1;
            const dR = endX - x + 1;
            const dT = y - startY + 1;
            const dB = endY - y + 1;

            // Using inverse square weighting to blend edge pixels
            const wL = 1 / Math.pow(dL, 2);
            const wR = 1 / Math.pow(dR, 2);
            const wT = 1 / Math.pow(dT, 2);
            const wB = 1 / Math.pow(dB, 2);

            const totalW = wL + wR + wT + wB;

            const cL = getPixel(startX - 1, y);
            const cR = getPixel(endX + 1, y);
            const cT = getPixel(x, startY - 1);
            const cB = getPixel(x, endY + 1);

            const idx = (y * canvas.width + x) * 4;
            data[idx] = (cL[0]*wL + cR[0]*wR + cT[0]*wT + cB[0]*wB) / totalW;
            data[idx+1] = (cL[1]*wL + cR[1]*wR + cT[1]*wT + cB[1]*wB) / totalW;
            data[idx+2] = (cL[2]*wL + cR[2]*wR + cT[2]*wT + cB[2]*wB) / totalW;
            data[idx+3] = (cL[3]*wL + cR[3]*wR + cT[3]*wT + cB[3]*wB) / totalW;
        }
    }

    // Apply a quick localized 3x3 box blur on the filled patch to smooth out streaking
    const blurredData = new Uint8ClampedArray(data);
    for (let y = startY; y <= endY; y++) {
        for (let x = startX; x <= endX; x++) {
            let r=0, g=0, b=0, a=0, count=0;
            // Accumulate neighboring pixels
            for(let ky=-1; ky<=1; ky++) {
                for(let kx=-1; kx<=1; kx++) {
                    let nx = x + kx;
                    let ny = y + ky;
                    if(nx >= 0 && nx < canvas.width && ny >= 0 && ny < canvas.height) {
                        const idx = (ny * canvas.width + nx) * 4;
                        r += data[idx];
                        g += data[idx+1];
                        b += data[idx+2];
                        a += data[idx+3];
                        count++;
                    }
                }
            }
            const idx = (y * canvas.width + x) * 4;
            blurredData[idx] = r / count;
            blurredData[idx+1] = g / count;
            blurredData[idx+2] = b / count;
            blurredData[idx+3] = a / count;
        }
    }
    
    // Copy the smoothed pixels back into our main image data
    for (let y = startY; y <= endY; y++) {
        for (let x = startX; x <= endX; x++) {
             const idx = (y * canvas.width + x) * 4;
             data[idx] = blurredData[idx];
             data[idx+1] = blurredData[idx+1];
             data[idx+2] = blurredData[idx+2];
             data[idx+3] = blurredData[idx+3];
        }
    }

    ctx.putImageData(imgData, 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 Uncomfortable Guest Remover is a photo editing tool designed to remove unwanted objects or people from a specific area of an image. By selecting a target region, the tool uses a content-aware blending technique and localized smoothing to fill the selected area with pixels from the surrounding environment, creating a more seamless appearance. This tool is useful for cleaning up group photos, removing distractions from scenic landscapes, or erasing photobombers to improve the overall composition of a picture.

Leave a Reply

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