Please bookmark this page to avoid losing your image tool!

Image Line Edge Color Transformer

(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.
/**
 * Detects edges in an image using the Sobel operator and transforms their color.
 *
 * @param {Image} originalImg The source Image object to process.
 * @param {string} [edgeColor='#000000'] The color for the detected edges (e.g., '#FF0000', 'red').
 * @param {number} [threshold=50] The sensitivity of the edge detection, from 0 to 255. Higher values result in fewer, sharper edges.
 * @param {string} [backgroundColor='#FFFFFF'] The background color for non-edge areas. Use 'transparent' for a transparent background.
 * @returns {HTMLCanvasElement} A canvas element with the transformed image.
 */
function processImage(originalImg, edgeColor = '#000000', threshold = 50, backgroundColor = '#FFFFFF') {
    /**
     * Helper function to parse various color string formats (hex, rgb, names) into an RGBA object.
     * @param {string} colorStr The color string to parse.
     * @returns {{r: number, g: number, b: number, a: number}} An object with RGBA components.
     */
    const parseColor = (colorStr) => {
        if (typeof colorStr !== 'string') {
             return { r: 0, g: 0, b: 0, a: 255 };
        }
        if (colorStr.toLowerCase() === 'transparent') {
            return { r: 0, g: 0, b: 0, a: 0 };
        }
        
        const tempElem = document.createElement('div');
        tempElem.style.color = colorStr;
        document.body.appendChild(tempElem);
        const computedColor = window.getComputedStyle(tempElem).color;
        document.body.removeChild(tempElem);

        const match = computedColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
        if (match) {
            return {
                r: parseInt(match[1], 10),
                g: parseInt(match[2], 10),
                b: parseInt(match[3], 10),
                a: match[4] !== undefined ? Math.round(parseFloat(match[4]) * 255) : 255
            };
        }
        return { r: 0, g: 0, b: 0, a: 255 }; // Fallback to black
    };

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

    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    ctx.drawImage(originalImg, 0, 0, width, height);
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    // Create a grayscale representation for edge detection
    const grayscaleData = new Uint8ClampedArray(width * height);
    for (let i = 0; i < data.length; i += 4) {
        const gray = data[i] * 0.299 + data[i + 1] * 0.587 + data[i + 2] * 0.114;
        grayscaleData[i / 4] = gray;
    }

    // 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] ];
    
    // Use a Float32Array to store magnitudes which can exceed 255
    const magnitudeData = new Float32Array(width * height);
    let maxMagnitude = 0;

    // Apply Sobel operator to each pixel (ignoring the 1px border)
    for (let y = 1; y < height - 1; y++) {
        for (let x = 1; x < width - 1; x++) {
            let gx = 0;
            let gy = 0;
            for (let ky = -1; ky <= 1; ky++) {
                for (let kx = -1; kx <= 1; kx++) {
                    const grayValue = grayscaleData[(y + ky) * width + (x + kx)];
                    gx += grayValue * Gx[ky + 1][kx + 1];
                    gy += grayValue * Gy[ky + 1][kx + 1];
                }
            }
            
            // Using Math.abs for performance over Math.sqrt
            const magnitude = Math.abs(gx) + Math.abs(gy);
            const currentIndex = y * width + x;
            magnitudeData[currentIndex] = magnitude;
            
            if (magnitude > maxMagnitude) {
                maxMagnitude = magnitude;
            }
        }
    }

    const newImageData = ctx.createImageData(width, height);
    const newData = newImageData.data;
    const edgeRgba = parseColor(edgeColor);
    const bgRgba = parseColor(backgroundColor);

    // Build the final image, coloring pixels based on normalized magnitude and threshold
    for (let i = 0; i < magnitudeData.length; i++) {
        const offset = i * 4;
        // Normalize magnitude to a 0-255 range to make the threshold consistent
        const normalizedMagnitude = (magnitudeData[i] / maxMagnitude) * 255;
        
        if (normalizedMagnitude > threshold) {
            newData[offset] = edgeRgba.r;
            newData[offset + 1] = edgeRgba.g;
            newData[offset + 2] = edgeRgba.b;
            newData[offset + 3] = edgeRgba.a;
        } else {
            newData[offset] = bgRgba.r;
            newData[offset + 1] = bgRgba.g;
            newData[offset + 2] = bgRgba.b;
            newData[offset + 3] = bgRgba.a;
        }
    }

    ctx.putImageData(newImageData, 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 Line Edge Color Transformer is a tool that processes images to detect edges using the Sobel operator and applies customizable color transformations to those edges. Users can specify the color of the detected edges, the sensitivity of the detection, and the background color for non-edge areas. This tool can be particularly useful for generating artistic effects in images, creating stylized graphics for design projects, enhancing visual elements in presentations, or simply experimenting with image processing techniques.

Leave a Reply

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