Please bookmark this page to avoid losing your image tool!

Image Scaffold Structure Filter Effect 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.
function processImage(originalImg, threshold = 30, lineColor = "black", lineWidth = 1, backgroundColor = "white") {
    const width = originalImg.width;
    const height = originalImg.height;

    // Create output canvas
    const outputCanvas = document.createElement('canvas');
    outputCanvas.width = width;
    outputCanvas.height = height;
    
    const outCtx = outputCanvas.getContext('2d');

    // Handle cases where image dimensions might be zero or context cannot be retrieved
    if (!outCtx || width === 0 || height === 0) {
        if (outCtx) { // Context exists, but dimensions might be 0
            outCtx.fillStyle = backgroundColor;
            outCtx.fillRect(0, 0, width, height); //fillRect on 0-dim canvas does nothing
        }
        // Log error if context failed for non-zero dimensions, otherwise it's expected for 0-dim
        if (!outCtx && (width !== 0 && height !== 0)) {
            console.error("Could not get 2D context for output canvas.");
        }
        return outputCanvas; 
    }

    // Fill background
    outCtx.fillStyle = backgroundColor;
    outCtx.fillRect(0, 0, width, height);

    // Create temporary canvas to get pixel data of original image
    // This is necessary because we need access to raw pixel data.
    const tempCanvas = document.createElement('canvas');
    tempCanvas.width = width;
    tempCanvas.height = height;
    const tempCtx = tempCanvas.getContext('2d');
    
    if (!tempCtx) {
        console.error("Could not get 2D context for temporary canvas. This is unexpected.");
        // Return canvas with only background drawn
        return outputCanvas;
    }
    
    tempCtx.drawImage(originalImg, 0, 0, width, height);
    
    let imageData;
    try {
        imageData = tempCtx.getImageData(0, 0, width, height);
    } catch (e) {
        console.error("Could not get image data. This may be due to cross-origin restrictions on the image.", e);
        // Return canvas with only background drawn, as we cannot process pixel data.
        return outputCanvas;
    }
    const data = imageData.data;

    // Convert image to grayscale and store values in a flat array
    // Using Uint8Array automatically truncates/clamps float results to 0-255 integers.
    const grayValues = new Uint8Array(width * height);
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i+1];
        const b = data[i+2];
        // Using ITU-R BT.709 luma coefficients (common for sRGB color space)
        const gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;
        grayValues[i / 4] = gray; // Store grayscale value (0-255)
    }

    outCtx.strokeStyle = lineColor;
    // Ensure lineWidth is a positive value; canvas behavior for 0 or negative lineWidth can vary.
    // A very smalllineWidth (e.g., 0.1) will still be visible. Let's ensure it's at least 0.1.
    outCtx.lineWidth = Math.max(0.1, lineWidth); 
    
    // Default lineCap ('butt') and lineJoin ('miter') are suitable for a "scaffold" look.

    outCtx.beginPath(); // Start a new path for all detected edge lines

    // Iterate through pixels to find edges by comparing with neighbors.
    // Loops stop at width-1 and height-1 because we need to access (x+1) and (y+1).
    for (let y = 0; y < height - 1; y++) { 
        for (let x = 0; x < width - 1; x++) { 
            const currentIndex = y * width + x;
            const currentGray = grayValues[currentIndex];
            
            // Check difference with pixel to the right (detects vertical edges)
            const rightGray = grayValues[currentIndex + 1]; // Pixel (x+1, y)
            if (Math.abs(currentGray - rightGray) > threshold) {
                // Draw a 1-pixel-long vertical line segment.
                // It's positioned at x+0.5 to align with the boundary between pixels.
                outCtx.moveTo(x + 0.5, y); 
                outCtx.lineTo(x + 0.5, y + 1);
            }

            // Check difference with pixel below (detects horizontal edges)
            const bottomGray = grayValues[currentIndex + width]; // Pixel (x, y+1)
            if (Math.abs(currentGray - bottomGray) > threshold) {
                // Draw a 1-pixel-long horizontal line segment.
                // It's positioned at y+0.5 for similar boundary alignment.
                outCtx.moveTo(x, y + 0.5);
                outCtx.lineTo(x + 1, y + 0.5);
            }
        }
    }
    outCtx.stroke(); // Draw all line segments collected in the path

    return outputCanvas;
}

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 Scaffold Structure Filter Effect Tool is designed to enhance images by applying a scaffold-like structure effect, highlighting edges within the image. Users can upload images and customize parameters such as edge detection sensitivity, line color, line width, and background color. This tool is suitable for various applications, including graphic design, architectural visualizations, and educational purposes, where visual emphasis on structure and contour is desired. It provides an effective way to create artistic representations or to analyze shapes and structures within photographs.

Leave a Reply

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