Please bookmark this page to avoid losing your image tool!

Image Sign Language 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, posterizationLevelsInput = 4, contrastFactorInput = 1.2) {
    const canvas = document.createElement('canvas');
    // Using { willReadFrequently: true } can provide a performance hint for contexts
    // where getImageData/putImageData are used frequently. Not strictly necessary but good practice.
    const ctx = canvas.getContext('2d', { willReadFrequently: true });

    // Use naturalWidth/Height for intrinsic dimensions of the image.
    // Fallback to width/height if naturalWidth/Height are 0 (e.g., if image is an SVG or not fully loaded in some edge cases).
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;

    // If the image dimensions are zero (e.g., image not loaded or is a 0x0 image),
    // set canvas size to 0x0 and return it.
    if (width === 0 || height === 0) {
        canvas.width = 0;
        canvas.height = 0;
        // console.warn("processImage: Original image has zero width or height. Ensure the image is loaded.");
        return canvas;
    }

    canvas.width = width;
    canvas.height = height;

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

    // --- Parameter Sanitization and Validation ---
    let posterizationLevels = Number(posterizationLevelsInput);
    // If input is not a number or NaN, use the default value (4).
    if (isNaN(posterizationLevels)) {
        posterizationLevels = 4; 
    }
    // Ensure posterizationLevels is an integer and at least 2 (minimum for posterization).
    posterizationLevels = Math.max(2, Math.floor(posterizationLevels));

    let contrastFactor = Number(contrastFactorInput);
    // If input is not a number or NaN, use the default value (1.2).
    if (isNaN(contrastFactor)) {
        contrastFactor = 1.2;
    }

    // Get the pixel data from the canvas.
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    // --- Apply Image Processing Effects ---
    // Pre-calculate divisor for posterization step for efficiency.
    // This is (levels - 1). Since levels is guaranteed to be >= 2, divisor >= 1.
    const posterizationDivisor = posterizationLevels - 1;

    // Iterate through each pixel (each pixel has 4 components: R, G, B, A).
    for (let i = 0; i < data.length; i += 4) {
        let r = data[i];
        let g = data[i + 1];
        let b = data[i + 2];
        // Alpha channel (data[i+3]) is preserved.

        // 1. Apply Contrast Adjustment
        // Skip if contrastFactor is 1.0 (no change).
        if (contrastFactor !== 1.0) {
            // Adjust contrast using the formula: NewValue = (OldValue - MidPoint) * Factor + MidPoint
            // A common midpoint for 8-bit color values (0-255) is 127.5.
            const midpoint = 127.5; 
            r = (r - midpoint) * contrastFactor + midpoint;
            g = (g - midpoint) * contrastFactor + midpoint;
            b = (b - midpoint) * contrastFactor + midpoint;

            // Clamp values to the valid [0, 255] range and round to nearest integer.
            r = Math.max(0, Math.min(255, Math.round(r)));
            g = Math.max(0, Math.min(255, Math.round(g)));
            b = Math.max(0, Math.min(255, Math.round(b)));
        }

        // 2. Apply Posterization
        // This reduces the number of distinct color shades for each channel.
        // The step value determines the intensity of quantization.
        const step = 255 / posterizationDivisor; // posterizationDivisor is (levels-1)
        r = Math.round(r / step) * step;
        g = Math.round(g / step) * step;
        b = Math.round(b / step) * step;
        // No additional clamping needed for r,g,b after posterization if inputs were already clamped,
        // as Math.round(val/step)*step for val in [0,255] will stay in [0,255].
        
        // Update the pixel data array with the modified RGB values.
        data[i] = r;
        data[i + 1] = g;
        data[i + 2] = b;
    }

    // Write the modified pixel data back to 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 Sign Language Filter Effect Tool enables users to process images by applying posterization and contrast adjustments, creating stylized visuals that can enhance the clarity of sign language elements in photographs. This tool is particularly useful for educators, interpreters, and professionals working with the Deaf community, allowing them to produce clear and engaging visual content. Additionally, it can be used by artists seeking to explore creative effects in their imagery, enhancing color contrast and simplifying shades to convey messages effectively.

Leave a Reply

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