Please bookmark this page to avoid losing your image tool!

Image Object Extractor By Color

(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.
/**
 * Extracts objects from an image based on a target color and tolerance.
 * Pixels matching the target color (within the given tolerance) are kept,
 * while other pixels are made transparent.
 *
 * @param {HTMLImageElement} originalImg The source image element. Should be fully loaded.
 * @param {number|string} [targetColorR=0] The red component of the target color (0-255).
 * @param {number|string} [targetColorG=0] The green component of the target color (0-255).
 * @param {number|string} [targetColorB=0] The blue component of the target color (0-255).
 * @param {number|string} [tolerance=30] The color matching tolerance. This is the maximum allowed
 *                                 Euclidean distance between a pixel's color and the target
 *                                 color in the RGB color space. A higher value means
 *                                 a looser match. A common range is 0-100, max useful distance is ~442.
 * @returns {HTMLCanvasElement} A new canvas element containing the processed image.
 *                              Pixels matching the criteria retain their original color and alpha.
 *                              Non-matching pixels are made transparent.
 *                              Returns a canvas with an error message if processing fails.
 */
function processImage(originalImg, targetColorR = 0, targetColorG = 0, targetColorB = 0, tolerance = 30) {
    const canvas = document.createElement('canvas');
    // Optimization hint for frequent read/write operations on the context.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Use naturalWidth/Height for intrinsic dimensions, fallback to width/height if natural* are not available (e.g. for a canvas source)
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // If image has no dimensions (e.g., not loaded or it's a 0x0 image), return an empty canvas
    if (imgWidth === 0 || imgHeight === 0) {
        console.warn("Input image has zero dimensions. Returning an empty canvas.");
        // The canvas will be 0x0 if imgWidth/imgHeight are 0.
        return canvas;
    }

    // Draw the original image onto the canvas
    try {
        ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Error drawing image to canvas:", e);
        // Canvas is already sized. Get its context to display an error.
        const errorCtx = canvas.getContext('2d'); 
        errorCtx.fillStyle = 'rgba(230, 230, 230, 1)'; // Opaque light gray background
        errorCtx.fillRect(0, 0, canvas.width, canvas.height);
        
        errorCtx.fillStyle = 'red';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        // Responsive font size for error message
        const fontSize = Math.min(Math.max(canvas.width / 20, 10), 16);
        errorCtx.font = `bold ${fontSize}px Arial`;
        errorCtx.fillText('Error: Could not draw input image.', canvas.width / 2, canvas.height / 2);
        return canvas;
    }

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This error usually occurs due to cross-origin restrictions when the canvas becomes "tainted"
        console.error("Error getting ImageData (likely cross-origin issue):", e);
        const errorCtx = canvas.getContext('2d'); // Canvas already sized
        // Clear previous content (original image) and draw error message
        errorCtx.fillStyle = 'rgba(230, 230, 230, 1)'; // Opaque light gray background
        errorCtx.fillRect(0, 0, canvas.width, canvas.height);
        
        errorCtx.fillStyle = 'red';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        const fontSize = Math.min(Math.max(canvas.width / 25, 10), 16); // Slightly smaller font for potentially longer messages
        errorCtx.font = `bold ${fontSize}px Arial`;

        if (e.name === 'SecurityError') {
            // Provide a more specific message for common cross-origin issues
            errorCtx.fillText('Error: Image data inaccessible', canvas.width / 2, canvas.height / 2 - fontSize * 0.75);
            errorCtx.fillText('due to cross-origin policy.', canvas.width / 2, canvas.height / 2 + fontSize * 0.75);
        } else {
            errorCtx.fillText('Error: Cannot access pixel data.', canvas.width / 2, canvas.height / 2);
        }
        return canvas;
    }
    
    const data = imageData.data; // This is a Uint8ClampedArray: [R, G, B, A, R, G, B, A, ...]

    // Ensure parameters are numbers, as they might be passed as strings from HTML inputs
    const rT = Number(targetColorR);
    const gT = Number(targetColorG);
    const bT = Number(targetColorB);
    const tol = Number(tolerance);

    // Using squared Euclidean distance for color comparison to avoid costly Math.sqrt per pixel.
    // A pixel (r,g,b) matches the target (rT,gT,bT) if the distance is within tolerance:
    // sqrt((r-rT)^2 + (g-gT)^2 + (b-bT)^2) <= tol
    // which is equivalent to (r-rT)^2 + (g-gT)^2 + (b-bT)^2 <= tol^2
    const toleranceSquared = tol * tol;

    // Iterate through each pixel in the ImageData
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];     // Red component
        const g = data[i + 1]; // Green component
        const b = data[i + 2]; // Blue component
        // Alpha component is data[i+3]

        // Calculate squared distance to target color
        const dr = r - rT;
        const dg = g - gT;
        const db = b - bT;
        const distanceSquared = dr * dr + dg * dg + db * db;

        if (distanceSquared <= toleranceSquared) {
            // Pixel's color is within the tolerance. Keep it as is (preserve original color and alpha).
            // No changes needed for data[i], data[i+1], data[i+2], data[i+3].
        } else {
            // Pixel's color is not within the tolerance. Make this pixel transparent.
            data[i + 3] = 0; // Set alpha channel to 0
        }
    }

    // Put the modified pixel data back onto the canvas
    ctx.putImageData(imageData, 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 Object Extractor By Color is a web-based tool designed to extract objects from images based on a specified color and tolerance level. Users can input an image and select a target color (defined by RGB components) and a tolerance value to determine how closely pixels must match the target color. Pixels that match will retain their color, while others will be made transparent. This tool can be handy for graphic designers, digital artists, and content creators who need to isolate specific elements in images for use in projects, such as creating overlays, extracting logos, or preparing images for compositing in video editing.

Leave a Reply

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