Please bookmark this page to avoid losing your image tool!

Image Welded Seam Filter Effect Application

(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, strength = 1.0, direction = "top-left") {
    const canvas = document.createElement('canvas');
    // Use willReadFrequently for potential performance gain with multiple getImageData/putImageData calls
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Ensure the originalImg is loaded, otherwise width/height might be 0.
    // For this function's contract, we assume originalImg is a loaded Image object.
    const imgWidth = originalImg.naturalWidth || originalImg.width;
    const imgHeight = originalImg.naturalHeight || originalImg.height;

    if (imgWidth === 0 || imgHeight === 0) {
        console.error("Image has zero dimensions. Ensure it is loaded.");
        // Return an empty or error canvas
        canvas.width = 100; // Default small size
        canvas.height = 50;
        ctx.font = "12px Arial";
        ctx.fillStyle = "red";
        ctx.textAlign = "center";
        ctx.fillText("Error: Image not loaded or zero dimensions.", canvas.width / 2, canvas.height / 2);
        return canvas;
    }
    
    canvas.width = imgWidth;
    canvas.height = imgHeight;

    ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    let imageData;
    try {
        imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        console.error("Error getting image data for Welded Seam effect: ", e);
        // In case of error (e.g. tainted canvas from cross-origin image), return a canvas with an error message.
        ctx.clearRect(0,0,canvas.width, canvas.height); // Clear previous drawImage
        ctx.font = "14px Arial";
        ctx.fillStyle = "black"; // Use black for visibility on typical white backgrounds
        ctx.textAlign = "center";
        const message = e.name === 'SecurityError' ? "Error: Cannot process cross-origin image." : "Error: Could not get image data.";
        ctx.fillText(message, canvas.width / 2, canvas.height / 2, canvas.width * 0.9); // Add max width for text
        return canvas;
    }
    
    const data = imageData.data;
    const width = imgWidth;
    const height = imgHeight;

    const originalAlpha = new Uint8Array(width * height); // Store original alpha values
    const grayData = new Float32Array(width * height); // Store grayscale values with precision

    // 1. Convert image to grayscale and store original alpha values
    // Using Rec. 709 luma coefficients for grayscale conversion (common for digital displays).
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        const alpha = data[i + 3];
        
        const grayVal = 0.2126 * r + 0.7152 * g + 0.0722 * b;
        const pixelIndex = i / 4;
        grayData[pixelIndex] = grayVal;
        originalAlpha[pixelIndex] = alpha;
    }

    // Determine displacement (dx, dy) for sampling based on 'direction' parameter.
    // This displacement simulates a light source: dx, dy define the offset for sampling.
    // Light is effectively from the direction (-dx, -dy).
    // E.g., if dx=1, dy=1, light comes from top-left.
    let dx = 0, dy = 0;
    switch (String(direction).toLowerCase()) { // Ensure direction is treated as a string
        case "top":         dx = 0; dy = 1; break;
        case "top-right":   dx = -1; dy = 1; break;
        case "left":        dx = 1; dy = 0; break;
        case "right":       dx = -1; dy = 0; break;
        case "bottom-left": dx = 1; dy = -1; break;
        case "bottom":      dx = 0; dy = -1; break;
        case "bottom-right":dx = -1; dy = -1; break;
        case "top-left":    // Default direction
        default:            dx = 1; dy = 1; break;
    }

    // Helper function to get a grayscale value from grayData, handling image boundaries by clamping coordinates.
    function getGrayClamped(x, y, sourceGrayData, w, h) {
        const clampedX = Math.max(0, Math.min(w - 1, x));
        const clampedY = Math.max(0, Math.min(h - 1, y));
        return sourceGrayData[clampedY * w + clampedX];
    }

    // 2. Apply the emboss-like effect (welded seam)
    // This iterates through each pixel, calculating its new value based on neighbors.
    for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
            // Sample two points: val_a from "uphill" (towards light), val_b from "downhill" (away from light).
            const val_a = getGrayClamped(x - dx, y - dy, grayData, width, height);
            const val_b = getGrayClamped(x + dx, y + dy, grayData, width, height);

            // Calculate the difference, scale by strength, and offset by 128 (mid-gray).
            // Ensure 'strength' is treated as a number.
            let finalPixelVal = 128 + (val_a - val_b) * Number(strength);
            
            // Clamp the final pixel value to the 0-255 range for RGB channels.
            finalPixelVal = Math.max(0, Math.min(255, finalPixelVal));

            const dataIndex = (y * width + x) * 4;
            data[dataIndex] = finalPixelVal;     // Red channel
            data[dataIndex + 1] = finalPixelVal; // Green channel
            data[dataIndex + 2] = finalPixelVal; // Blue channel
            // Restore the original alpha value for the pixel.
            data[dataIndex + 3] = originalAlpha[dataIndex / 4]; 
        }
    }

    // Put the modified pixel data back onto the 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 Welded Seam Filter Effect Application allows users to apply an artistic effect simulating a welded seam look to their images. By processing images through a canvas, the tool utilizes grayscale values and directional sampling to create a visually striking, embossed effect. This effect can enhance the texture of images for creative projects, such as graphic design, digital art, or personal photography enhancement. Users can adjust parameters like strength and direction of the light source to customize the final appearance of the effect.

Leave a Reply

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