Please bookmark this page to avoid losing your image tool!

Image Subject Isolation And Custom Transformation 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.
/**
 * Isolates the main person from an image, applies clothing and body modifications,
 * and returns the result on a new canvas.
 *
 * This function is an advanced demonstration and requires loading external libraries,
 * so it may take a few moments to run the first time.
 *
 * @param {HTMLImageElement} originalImg The original image to process.
 * @param {number} [fatness=1.2] A factor to scale the person's width. 1.0 is no change, 1.2 is 20% wider.
 * @param {number} [dressShortness=0.6] A factor for dress length on the legs (0.0=mini, 1.0=maxi).
 * @param {string} [dressColor='red'] The color to make the dress. Accepts any valid CSS color.
 * @param {string} [tightsColor='black'] The color for the tights. Accepts any valid CSS color.
 * @returns {Promise<HTMLCanvasElement>} A promise that resolves to a new canvas element with the transformed person on a transparent background.
 */
async function processImage(originalImg, fatness = 1.2, dressShortness = 0.6, dressColor = 'red', tightsColor = 'black') {

    // Helper to dynamically load a script only once.
    const loadScript = (url) => {
        return new Promise((resolve, reject) => {
            if (document.querySelector(`script[src="${url}"]`)) {
                resolve();
                return;
            }
            const script = document.createElement('script');
            script.src = url;
            script.onload = () => resolve();
            script.onerror = () => reject(new Error(`Script load error for ${url}`));
            document.head.appendChild(script);
        });
    };

    // 1. Load TensorFlow.js and BodyPix models
    try {
        await Promise.all([
            loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core@3.18.0/dist/tf-core.min.js'),
            loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter@3.18.0/dist/tf-converter.min.js'),
            loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl@3.18.0/dist/tf-backend-webgl.min.js'),
            loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/body-pix@2.2.0/dist/body-pix.min.js')
        ]);
    } catch (error) {
        console.error("Failed to load required AI models.", error);
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = originalImg.width;
        errorCanvas.height = originalImg.height;
        const ctx = errorCanvas.getContext('2d');
        ctx.drawImage(originalImg, 0, 0);
        ctx.fillStyle = 'rgba(255, 0, 0, 0.7)';
        ctx.font = '16px sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('Error: Could not load AI model files.', errorCanvas.width / 2, errorCanvas.height / 2);
        return errorCanvas;
    }


    // 2. Setup canvases
    const w = originalImg.naturalWidth;
    const h = originalImg.naturalHeight;

    const finalCanvas = document.createElement('canvas');
    finalCanvas.width = w;
    finalCanvas.height = h;
    const finalCtx = finalCanvas.getContext('2d');

    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = w;
    tempCanvas.height = h;
    const tempCtx = tempCanvas.getContext('2d');

    // Get original image pixel data
    const originalCanvas = document.createElement('canvas');
    originalCanvas.width = w;
    originalCanvas.height = h;
    const originalCtx = originalCanvas.getContext('2d');
    originalCtx.drawImage(originalImg, 0, 0);
    const originalImageData = originalCtx.getImageData(0, 0, w, h);

    // 3. Load BodyPix and perform segmentation
    const net = await bodyPix.load({
        architecture: 'MobileNetV1',
        outputStride: 16,
        multiplier: 0.75,
        quantBytes: 2
    });
    const segmentation = await net.segmentPersonParts(originalImg, {
        flipHorizontal: false,
        internalResolution: 'medium',
        segmentationThreshold: 0.7
    });

    if (segmentation.allPoses.length === 0) {
        finalCtx.drawImage(originalImg, 0, 0);
        finalCtx.fillStyle = 'rgba(255, 0, 0, 0.7)';
        finalCtx.font = '20px sans-serif';
        finalCtx.textAlign = 'center';
        finalCtx.fillText('Could not detect a person in the image.', w / 2, h / 2);
        return finalCanvas;
    }

    // 4. Define body part groups and calculate clothing boundaries
    const TORSO_PARTS = new Set([12, 13]);
    const LEG_PARTS = new Set([14, 15, 16, 17, 18, 19, 20, 21]);
    
    let clothingMinY = h;
    let clothingMaxY = 0;
    const clothingParts = new Set([...TORSO_PARTS, ...LEG_PARTS]);
    for (let i = 0; i < segmentation.data.length; i++) {
        if (clothingParts.has(segmentation.data[i])) {
            const y = Math.floor(i / w);
            if (y < clothingMinY) clothingMinY = y;
            if (y > clothingMaxY) clothingMaxY = y;
        }
    }
    const dressCutoffY = clothingMinY + (clothingMaxY - clothingMinY) * dressShortness;

    // Helper to get RGB values from a CSS color string
    const colorCache = {};
    const getRgb = (colorStr) => {
        if (colorCache[colorStr]) return colorCache[colorStr];
        const colorCtx = document.createElement('canvas').getContext('2d');
        colorCtx.fillStyle = colorStr;
        colorCtx.fillRect(0, 0, 1, 1);
        const [r, g, b] = colorCtx.getImageData(0, 0, 1, 1).data;
        colorCache[colorStr] = { r, g, b };
        return colorCache[colorStr];
    };
    const dressRgb = getRgb(dressColor);
    const tightsRgb = getRgb(tightsColor);

    // 5. Recolor the person on a temporary canvas
    const tempImageData = tempCtx.createImageData(w, h);
    for (let i = 0; i < segmentation.data.length; i++) {
        const partId = segmentation.data[i];
        if (partId === -1) continue; // Skip background

        const offset = i * 4;
        const y = Math.floor(i / w);
        let newColor = null;

        if (TORSO_PARTS.has(partId)) {
            newColor = dressRgb;
        } else if (LEG_PARTS.has(partId)) {
            newColor = y < dressCutoffY ? dressRgb : tightsRgb;
        }

        if (newColor) {
            tempImageData.data[offset] = newColor.r;
            tempImageData.data[offset + 1] = newColor.g;
            tempImageData.data[offset + 2] = newColor.b;
            tempImageData.data[offset + 3] = originalImageData.data[offset + 3]; // Preserve alpha
        } else {
            // Keep original color for other parts (head, arms, feet)
            tempImageData.data[offset] = originalImageData.data[offset];
            tempImageData.data[offset + 1] = originalImageData.data[offset + 1];
            tempImageData.data[offset + 2] = originalImageData.data[offset + 2];
            tempImageData.data[offset + 3] = originalImageData.data[offset + 3];
        }
    }
    tempCtx.putImageData(tempImageData, 0, 0);

    // 6. Apply "fatness" transformation by stretching the result
    let minX = w, minY = h, maxX = 0, maxY = 0;
    for (let y = 0; y < h; y++) {
        for (let x = 0; x < w; x++) {
            if (tempImageData.data[(y * w + x) * 4 + 3] > 0) {
                if (x < minX) minX = x;
                if (x > maxX) maxX = x;
                if (y < minY) minY = y;
                if (y > maxY) maxY = y;
            }
        }
    }

    const personWidth = maxX - minX;
    const personHeight = maxY - minY;

    if (personWidth > 0 && personHeight > 0) {
        const newWidth = personWidth * fatness;
        const newX = minX - (newWidth - personWidth) / 2;

        finalCtx.drawImage(
            tempCanvas,
            minX, minY, personWidth, personHeight,
            newX, minY, newWidth, personHeight
        );
    }
    
    // 7. Return the final canvas
    return finalCanvas;
}

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 Subject Isolation and Custom Transformation Tool is designed to manipulate photographs by isolating the main person in the image and applying customizable transformations. Users can alter aspects such as body width, dress length, and colors for clothing items like dresses and tights. This tool utilizes advanced AI models to segment and identify body parts, allowing for detailed modifications. It can be particularly useful for fashion design, social media, or personal projects where you want to experiment with different looks on a subject without physically changing their attire.

Leave a Reply

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