Please bookmark this page to avoid losing your image tool!

Image Bauhaus 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, paletteString = "FF0000,FFFF00,0000FF,000000,FFFFFF") {
    // Helper function to convert hex color string (e.g., "FF0000" or "#FF0000") to an RGB array [r, g, b]
    // Returns null if the hex string is invalid.
    function hexToRgb(hex) {
        hex = hex.replace(/^#/, ''); // Remove leading '#' if present

        // Expand shorthand hex form (e.g., "F00" to "FF0000")
        if (hex.length === 3) {
            hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
        }

        // Check if the hex string is valid (6 hex characters)
        if (!/^[0-9A-Fa-f]{6}$/.test(hex)) {
            return null; 
        }

        const r = parseInt(hex.substring(0, 2), 16);
        const g = parseInt(hex.substring(2, 4), 16);
        const b = parseInt(hex.substring(4, 6), 16);
        return [r, g, b];
    }

    // Helper function to calculate the squared Euclidean distance between two RGB colors.
    // Using squared distance for comparison is more efficient as it avoids Math.sqrt().
    function colorDistanceSquared(rgb1, rgb2) {
        const dr = rgb1[0] - rgb2[0];
        const dg = rgb1[1] - rgb2[1];
        const db = rgb1[2] - rgb2[2];
        return dr * dr + dg * dg + db * db;
    }

    // Parse the paletteString:
    // 1. Split the string by commas.
    // 2. Trim whitespace from each resulting hex string.
    // 3. Filter out any empty strings that might result (e.g., from "color1,,color2").
    // 4. Convert valid hex strings to RGB arrays. Invalid hex strings become null.
    // 5. Filter out nulls (results of invalid hex conversions).
    let parsedPalette = paletteString
        .split(',')
        .map(hex => hex.trim())
        .filter(hex => hex.length > 0) 
        .map(hex => hexToRgb(hex))
        .filter(rgbArray => rgbArray !== null);

    // If the parsedPalette is empty (e.g., paletteString was empty, malformed, or contained no valid colors),
    // fall back to a default Bauhaus-inspired palette.
    if (parsedPalette.length === 0) {
        parsedPalette = [
            [255, 0, 0],   // Red
            [255, 255, 0], // Yellow
            [0, 0, 255],   // Blue
            [0, 0, 0],     // Black
            [255, 255, 255]  // White
        ];
    }

    // Create a canvas element to draw the processed image on.
    const canvas = document.createElement('canvas');
    // Use { willReadFrequently: true } for potential performance optimization with getImageData/putImageData.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Set canvas dimensions to match the original image.
    // naturalWidth/naturalHeight are used as they give the intrinsic dimensions of the image.
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;

    // If the image has no dimensions (e.g., it's not loaded yet or is an invalid image),
    // return the empty canvas. The caller should ensure the image is loaded.
    if (canvas.width === 0 || canvas.height === 0) {
        return canvas;
    }

    // Draw the original image onto the canvas.
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    // Get the pixel data from the canvas.
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data; // This is a Uint8ClampedArray: [R,G,B,A, R,G,B,A, ...]

    // Iterate over each pixel in the imageData.
    // Each pixel consists of 4 components: Red, Green, Blue, Alpha.
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        // The Alpha channel (data[i+3]) is preserved from the original image.

        // Find the color in the palette that is closest to the current pixel's color.
        // Initialize with the first color in the palette.
        let closestColorInPalette = parsedPalette[0];
        let minSquaredDistance = colorDistanceSquared([r, g, b], closestColorInPalette);

        // Iterate through the rest of the palette colors (if any) to find a closer match.
        for (let j = 1; j < parsedPalette.length; j++) {
            const currentPaletteColor = parsedPalette[j];
            const squaredDistance = colorDistanceSquared([r, g, b], currentPaletteColor);

            if (squaredDistance < minSquaredDistance) {
                minSquaredDistance = squaredDistance;
                closestColorInPalette = currentPaletteColor;
            }

            // Optimization: if a distance of 0 is found, it's a perfect match.
            // No need to check other palette colors for this pixel.
            if (minSquaredDistance === 0) {
                break;
            }
        }

        // Update the pixel's RGB values to those of the closest palette color.
        data[i] = closestColorInPalette[0];     // Red
        data[i + 1] = closestColorInPalette[1]; // Green
        data[i + 2] = closestColorInPalette[2]; // Blue
    }

    // Put the modified pixel data back onto the canvas.
    ctx.putImageData(imageData, 0, 0);

    // Return the canvas element with the Bauhaus-filtered image.
    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 Bauhaus Filter Effect Tool allows users to apply a distinctive Bauhaus-inspired color palette to their images. By selecting a palette of colors, you can transform ordinary photographs into artwork reminiscent of the Bauhaus movement, which emphasizes bold, geometric shapes and vibrant colors. This tool is useful for artists, graphic designers, and anyone looking to add a creative touch to their images by experimenting with color and artistic filters. Ideal for enhancing visuals for social media, digital artwork, or personal projects, the tool is easy to use and accessible online.

Leave a Reply

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