Please bookmark this page to avoid losing your image tool!

Image Contour Line 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, numLevels = 5, sensitivity = 5, lineColor = "black", backgroundColor = "white") {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    canvas.width = originalImg.naturalWidth || originalImg.width;
    canvas.height = originalImg.naturalHeight || originalImg.height;

    // Ensure width and height are not zero to prevent errors
    if (canvas.width === 0 || canvas.height === 0) {
        // Return an empty canvas or handle as an error
        console.warn("Image has zero width or height.");
        return canvas;
    }

    // Draw original image to get its pixel data
    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 if the image is tainted (e.g., cross-origin)
        console.error("Could not get image data: ", e);
        // Draw a placeholder or return the original (or an empty canvas)
        ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear canvas
        ctx.fillStyle = "red";
        ctx.font = "16px Arial";
        ctx.textAlign = "center";
        ctx.fillText("Error: Cannot process cross-origin image.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    
    const data = imageData.data;
    const width = canvas.width;
    const height = canvas.height;

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

    // Helper to parse color string to [r, g, b, a] array
    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);
        return tempCtx.getImageData(0, 0, 1, 1).data; // Returns Uint8ClampedArray [r, g, b, a]
    }

    const [lr, lg, lb, la] = parseColor(lineColor);
    const [br, bg, bb, ba] = parseColor(backgroundColor);

    // 1. Grayscale conversion
    const grayscaleData = new Uint8ClampedArray(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];
        const grayscale = 0.299 * r + 0.587 * g + 0.114 * b;
        grayscaleData[i / 4] = grayscale;
    }

    // 2. Quantization and Contour Detection
    const safeNumLevels = Math.max(1, numLevels); // Ensure numLevels is at least 1

    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            const currentIndex = y * width + x;
            const currentGrayscale = grayscaleData[currentIndex];
            const currentLevel = Math.floor(currentGrayscale * safeNumLevels / 256);

            let isContour = false;

            // Compare with right neighbor
            if (x + 1 < width) {
                const rightGrayscale = grayscaleData[currentIndex + 1];
                const rightLevel = Math.floor(rightGrayscale * safeNumLevels / 256);
                if (currentLevel !== rightLevel && Math.abs(currentGrayscale - rightGrayscale) >= sensitivity) {
                    isContour = true;
                }
            }

            // Compare with bottom neighbor (if not already a contour)
            if (!isContour && y + 1 < height) {
                const bottomGrayscale = grayscaleData[currentIndex + width];
                const bottomLevel = Math.floor(bottomGrayscale * safeNumLevels / 256);
                if (currentLevel !== bottomLevel && Math.abs(currentGrayscale - bottomGrayscale) >= sensitivity) {
                    isContour = true;
                }
            }
            
            const outputPixelIndex = currentIndex * 4;
            if (isContour) {
                outputData[outputPixelIndex] = lr;
                outputData[outputPixelIndex + 1] = lg;
                outputData[outputPixelIndex + 2] = lb;
                outputData[outputPixelIndex + 3] = la;
            } else {
                outputData[outputPixelIndex] = br;
                outputData[outputPixelIndex + 1] = bg;
                outputData[outputPixelIndex + 2] = bb;
                outputData[outputPixelIndex + 3] = ba;
            }
        }
    }

    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 Contour Line Filter Effect Tool allows users to apply a contour line effect to images. By processing the original image, this tool identifies significant boundaries based on color changes and displays them in a specified line color against a chosen background color. It offers customizable parameters including the number of contour levels and sensitivity for edge detection. This tool is useful for graphic designers, artists, and anyone looking to create stylized images or enhance visual elements in photographs. Typical applications include creating art pieces, designing graphics with distinctive outlines, and adding artistic effects in various digital projects.

Leave a Reply

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