Please bookmark this page to avoid losing your image tool!

Image Circuit Board 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, boardColorStr = "darkgreen", traceColorStr = "#B87333", componentColorStr = "dimgray", edgeThreshold = 200, componentLuminanceThreshold = 128) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Use naturalWidth/Height to ensure the image is loaded and get correct dimensions
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Image not loaded or dimensions are zero.");
        // Return a minimal canvas to avoid errors downstream
        canvas.width = 1; 
        canvas.height = 1;
        ctx.fillStyle = 'red'; // Indicate error
        ctx.fillRect(0,0,1,1);
        return canvas;
    }

    canvas.width = imgWidth;
    canvas.height = imgHeight;
    
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    } catch (e) {
        // This can happen due to tainted canvas (CORS) if image is cross-origin
        console.error("Could not get image data for processing (CORS issue?):", e);
        // Return the canvas with the original image drawn if processing is not possible
        return canvas; 
    }
    
    const data = imageData.data; // Source pixel data
    const width = imageData.width;
    const height = imageData.height;

    const outputImageData = ctx.createImageData(width, height);
    const outputData = outputImageData.data; // Target pixel data

    // Helper function to parse color strings (e.g., "red", "#FF0000", "rgb(255,0,0)")
    function parseColor(colorStr) {
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 1;
        tempCanvas.height = 1;
        const tempCtx = tempCanvas.getContext('2d');
        tempCtx.fillStyle = colorStr;
        tempCtx.fillRect(0, 0, 1, 1);
        const d = tempCtx.getImageData(0, 0, 1, 1).data;
        return { r: d[0], g: d[1], b: d[2] };
    }

    const finalBoardColor = parseColor(boardColorStr);
    const finalTraceColor = parseColor(traceColorStr);
    const finalComponentColor = parseColor(componentColorStr);

    // Helper to get grayscale value of a pixel from imageData, handling boundaries by clamping
    function getGrayscale(sourceImageData, x, y, w, h) {
        const currentX = Math.max(0, Math.min(x, w - 1)); // Clamp x
        const currentY = Math.max(0, Math.min(y, h - 1)); // Clamp y
        const i = (currentY * w + currentX) * 4;
        // Standard NTSC/PAL luminance formula
        return 0.299 * sourceImageData.data[i] + 0.587 * sourceImageData.data[i + 1] + 0.114 * sourceImageData.data[i + 2];
    }

    // Sobel operator kernels
    const Gx = [
        [-1, 0, 1],
        [-2, 0, 2],
        [-1, 0, 1]
    ];
    const Gy = [
        [-1, -2, -1],
        [ 0,  0,  0],
        [ 1,  2,  1]
    ];

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            let gradX = 0;
            let gradY = 0;

            // Apply Sobel operator centered at (x,y)
            for (let ky = -1; ky <= 1; ky++) {
                for (let kx = -1; kx <= 1; kx++) {
                    const kernelGxVal = Gx[ky + 1][kx + 1];
                    const kernelGyVal = Gy[ky + 1][kx + 1];
                    
                    const grayVal = getGrayscale(imageData, x + kx, y + ky, width, height);
                    
                    gradX += kernelGxVal * grayVal;
                    gradY += kernelGyVal * grayVal;
                }
            }

            // Calculate magnitude of the gradient
            const magnitude = Math.sqrt(gradX * gradX + gradY * gradY);
            
            const outputIndex = (y * width + x) * 4;

            if (magnitude > edgeThreshold) { // This pixel is an "edge" -> trace
                outputData[outputIndex]     = finalTraceColor.r;
                outputData[outputIndex + 1] = finalTraceColor.g;
                outputData[outputIndex + 2] = finalTraceColor.b;
                outputData[outputIndex + 3] = 255; // Alpha
            } else { // Not an edge -> board or component
                const originalPixelIndex = (y * width + x) * 4;
                const r_orig = data[originalPixelIndex];
                const g_orig = data[originalPixelIndex + 1];
                const b_orig = data[originalPixelIndex + 2];
                // Luminance of the original pixel
                const originalLuminance = 0.299 * r_orig + 0.587 * g_orig + 0.114 * b_orig;

                let targetColor;
                let baseLuminanceFactor;

                if (originalLuminance > componentLuminanceThreshold) { // Brighter non-edge areas -> component like
                    targetColor = finalComponentColor;
                    // Modulate component color brightness slightly by original luminance (80%-100% range)
                    baseLuminanceFactor = 0.8 + 0.2 * (originalLuminance / 255.0); 
                } else { // Darker non-edge areas -> board like
                    targetColor = finalBoardColor;
                    // Modulate board color brightness by original luminance (50%-100% range) to give texture
                    baseLuminanceFactor = 0.5 + 0.5 * (originalLuminance / 255.0);
                }
                
                outputData[outputIndex]     = Math.min(255, Math.max(0, Math.round(targetColor.r * baseLuminanceFactor)));
                outputData[outputIndex + 1] = Math.min(255, Math.max(0, Math.round(targetColor.g * baseLuminanceFactor)));
                outputData[outputIndex + 2] = Math.min(255, Math.max(0, Math.round(targetColor.b * baseLuminanceFactor)));
                outputData[outputIndex + 3] = 255; // Alpha
            }
        }
    }

    ctx.putImageData(outputImageData, 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 Circuit Board Filter Effect Tool allows users to transform images into a circuit board-style design. By applying customizable colors for the board, traces, and components, this tool can emphasize edges and enhance the overall appearance of an image to resemble a printed circuit board. It can be particularly useful for graphic designers, hobbyists, and educators looking to create visually striking representations of technology-related themes or to visualize electronic schematics in a creative way.

Leave a Reply

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