Please bookmark this page to avoid losing your image tool!

Image Engineering Schematic 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.
async function processImage(originalImg, lineColor = '#0000FF', backgroundColor = '#F0F8FF', threshold = 128, invertLines = 0, gridColor = 'rgba(173, 216, 230, 0.5)', gridSize = 20, showGrid = 1) {
    // Validate input image
    if (!(originalImg instanceof HTMLImageElement) || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
        console.error("Invalid image input: Must be a loaded HTMLImageElement with dimensions greater than 0.");
        const errorCanvas = document.createElement('canvas');
        errorCanvas.width = 300; // Arbitrary size for error message
        errorCanvas.height = 100;
        const errorCtx = errorCanvas.getContext('2d');
        errorCtx.fillStyle = '#FFDDDD'; // Light red background for error
        errorCtx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
        errorCtx.strokeStyle = 'red';
        errorCtx.lineWidth = 1;
        errorCtx.strokeRect(0, 0, errorCanvas.width, errorCanvas.height);
        errorCtx.fillStyle = 'black';
        errorCtx.font = '16px Arial';
        errorCtx.textAlign = 'center';
        errorCtx.textBaseline = 'middle';
        errorCtx.fillText('Invalid Image Input', errorCanvas.width / 2, errorCanvas.height / 2);
        return errorCanvas;
    }

    // Normalize parameters
    threshold = Math.max(0, Math.min(255, Number(threshold)));
    const shouldInvertLines = Number(invertLines) === 1; // Convert 0/1 to boolean logic
    gridSize = Math.max(1, Number(gridSize)); // Ensure gridSize is at least 1
    const shouldShowGrid = Number(showGrid) === 1; // Convert 0/1 to boolean logic

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    const imgWidth = originalImg.naturalWidth;
    const imgHeight = originalImg.naturalHeight;
    canvas.width = imgWidth;
    canvas.height = imgHeight;

    // Helper function to parse a color string (hex, rgb, name) to an RGBA object
    // This is needed to apply the lineColor with its specific RGBA components to pixel data.
    function getRgbaFromColorString(colorStr) {
        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = 1;
        tempCanvas.height = 1;
        const tempCtx = tempCanvas.getContext('2d');
        
        // Important: Clear with transparent before filling to get correct alpha for fully transparent colors like 'transparent'
        tempCtx.clearRect(0,0,1,1); 
        tempCtx.fillStyle = colorStr; // Browser parses the color string
        tempCtx.fillRect(0, 0, 1, 1);
        
        const colorData = tempCtx.getImageData(0, 0, 1, 1).data;
        return { r: colorData[0], g: colorData[1], b: colorData[2], a: colorData[3] };
    }

    const parsedLineColor = getRgbaFromColorString(lineColor);

    // 1. Fill canvas with backgroundColor
    // The canvas fillStyle property can directly take CSS color strings.
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, imgWidth, imgHeight);

    // 2. Draw optional grid
    if (shouldShowGrid && gridSize > 0) {
        ctx.strokeStyle = gridColor;
        ctx.lineWidth = 0.5; // Use a thin line for the grid
        
        // Draw vertical grid lines
        for (let x = 0; x < imgWidth; x += gridSize) {
            ctx.beginPath();
            ctx.moveTo(x + 0.5, 0); // Adding 0.5 for sharper lines
            ctx.lineTo(x + 0.5, imgHeight);
            ctx.stroke();
        }
        // Draw horizontal grid lines
        for (let y = 0; y < imgHeight; y += gridSize) {
            ctx.beginPath();
            ctx.moveTo(0, y + 0.5);
            ctx.lineTo(imgWidth, y + 0.5);
            ctx.stroke();
        }
    }

    // 3. Process the image to create the schematic effect
    // Use a temporary canvas to draw the original image and access its pixel data
    const tempCanvasForImage = document.createElement('canvas');
    const tempCtxForImage = tempCanvasForImage.getContext('2d');
    tempCanvasForImage.width = imgWidth;
    tempCanvasForImage.height = imgHeight;
    
    tempCtxForImage.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
    
    let imageData;
    try {
        imageData = tempCtxForImage.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Error getting image data. This can happen with cross-origin images if CORS is not configured on the server.", e);
        // If getImageData fails, display an error on the canvas
        ctx.clearRect(0,0,canvas.width,canvas.height); // Clear previously drawn background/grid
        ctx.fillStyle = '#FFDDDD';
        ctx.fillRect(0,0,canvas.width, canvas.height);
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 1;
        ctx.strokeRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'black';
        ctx.font = '14px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText('Error processing image (CORS issue?)', canvas.width/2, canvas.height/2);
        return canvas;
    }
    
    const data = imageData.data; // Pixel data array: [R,G,B,A, R,G,B,A, ...]

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        
        // Convert pixel to grayscale using the luminance formula
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        
        let isLinePixel;
        if (shouldInvertLines) {
            // Lighter parts of the original image become lines
            isLinePixel = gray > threshold;
        } else {
            // Darker parts of the original image become lines
            isLinePixel = gray < threshold;
        }
        
        if (isLinePixel) {
            // Set pixel to line color
            data[i] = parsedLineColor.r;
            data[i + 1] = parsedLineColor.g;
            data[i + 2] = parsedLineColor.b;
            data[i + 3] = parsedLineColor.a; // Use alpha from parsedLineColor
        } else {
            // Make non-line parts transparent to let the background and grid show through
            data[i + 3] = 0; // Set Alpha to 0 (fully transparent)
        }
    }
    
    // 4. Draw the processed image data (which now contains the schematic lines) onto the main 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 Engineering Schematic Filter Effect Tool allows users to transform images into schematic style representations. This tool enables the customization of line colors, background colors, grid visibility, and thresholds for line detection. Common use cases include creating technical drawings or schematics from photographs, designing visual aids for engineering projects, or producing artistic renditions of pictures with a focus on outlines and structural elements. Users can also apply grid overlays to aid in alignment and scaling during design tasks.

Leave a Reply

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