Please bookmark this page to avoid losing your image tool!

Image Compression Artifact 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.
/**
 * Applies a compression artifact filter effect to an image.
 * This effect simulates blockiness and color quantization typical of lossy image compression.
 *
 * @param {Image} originalImg The original JavaScript Image object. It should be fully loaded.
 * @param {number | string} blockSize The size of the square blocks for processing (e.g., 8, 16).
 *                                    Processed as an integer. Default is 8.
 * @param {number | string} quantizationFactor A factor to control color quantization (e.g., 32, 64).
 *                                             Color components (0-255) will be mapped to multiples of this factor.
 *                                             Processed as an integer. Larger values mean fewer colors.
 *                                             A value of 1 means minimal color quantization (colors are averaged within blocks).
 *                                             Default is 32.
 * @returns {HTMLCanvasElement} A canvas element displaying the image with the compression artifacts.
 */
function processImage(originalImg, blockSize = 8, quantizationFactor = 32) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true }); // Opt-in for performance if available

    // Ensure the canvas has the same dimensions as the image
    const width = originalImg.naturalWidth || originalImg.width;
    const height = originalImg.naturalHeight || originalImg.height;
    canvas.width = width;
    canvas.height = height;

    if (width === 0 || height === 0) {
        // Handle cases where the image might not be loaded or is an empty image
        console.warn("Image has zero width or height. Returning empty canvas.");
        return canvas;
    }
    
    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, width, height);

    // --- Parameter Validation and Coercion ---
    let effBlockSize = Number(blockSize);
    if (isNaN(effBlockSize) || effBlockSize <= 0) {
        console.warn(`Invalid blockSize "${blockSize}". Must be a positive number. Using default 8.`);
        effBlockSize = 8;
    }
    effBlockSize = Math.round(effBlockSize); // Ensure integer block size

    let effQuantizationFactor = Number(quantizationFactor);
    if (isNaN(effQuantizationFactor) || effQuantizationFactor <= 0) {
        console.warn(`Invalid quantizationFactor "${quantizationFactor}". Must be a positive number. Using default 32.`);
        effQuantizationFactor = 32;
    } else if (effQuantizationFactor < 1) {
        // Factors between 0 and 1 (exclusive) would effectively increase precision or cause issues.
        // Round up to 1 for minimal effect (just averaging within blocks).
        console.warn(`quantizationFactor "${quantizationFactor}" is between 0 and 1. Using 1 (minimal color quantization).`);
        effQuantizationFactor = 1;
    }
    effQuantizationFactor = Math.round(effQuantizationFactor); // Ensure integer factor

    // Get image data to manipulate pixels
    const imageData = ctx.getImageData(0, 0, width, height);
    const data = imageData.data;

    // Iterate over the image in blocks
    for (let y = 0; y < height; y += effBlockSize) {
        for (let x = 0; x < width; x += effBlockSize) {
            let rSum = 0, gSum = 0, bSum = 0, aSum = 0;
            let numPixelsInBlock = 0;

            // Determine actual block dimensions, clamping at image edges
            const currentBlockWidth = Math.min(effBlockSize, width - x);
            const currentBlockHeight = Math.min(effBlockSize, height - y);

            // Iterate over the pixels in the current block to calculate average color
            for (let by = 0; by < currentBlockHeight; by++) {
                for (let bx = 0; bx < currentBlockWidth; bx++) {
                    const R_INDEX = ((y + by) * width + (x + bx)) * 4;
                    rSum += data[R_INDEX];
                    gSum += data[R_INDEX + 1];
                    bSum += data[R_INDEX + 2];
                    aSum += data[R_INDEX + 3];
                    numPixelsInBlock++;
                }
            }

            if (numPixelsInBlock === 0) continue;

            const avgR = rSum / numPixelsInBlock;
            const avgG = gSum / numPixelsInBlock;
            const avgB = bSum / numPixelsInBlock;
            const avgA = aSum / numPixelsInBlock;

            // Quantize the average color components (RGB)
            // Formula: C_quant = round(C_avg / factor) * factor
            // Clamp to 0-255 range.
            const quantR = Math.max(0, Math.min(255, Math.round(avgR / effQuantizationFactor) * effQuantizationFactor));
            const quantG = Math.max(0, Math.min(255, Math.round(avgG / effQuantizationFactor) * effQuantizationFactor));
            const quantB = Math.max(0, Math.min(255, Math.round(avgB / effQuantizationFactor) * effQuantizationFactor));
            
            // For alpha, use the rounded average value without strong quantization
            // to better preserve original transparency characteristics within the block.
            const finalA = Math.max(0, Math.min(255, Math.round(avgA)));

            // Fill the block in imageData with the new quantized average color
            for (let by = 0; by < currentBlockHeight; by++) {
                for (let bx = 0; bx < currentBlockWidth; bx++) {
                    const R_INDEX = ((y + by) * width + (x + bx)) * 4;
                    data[R_INDEX] = quantR;
                    data[R_INDEX + 1] = quantG;
                    data[R_INDEX + 2] = quantB;
                    data[R_INDEX + 3] = finalA; 
                }
            }
        }
    }

    // Put the modified image 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 Compression Artifact Filter Effect Tool allows users to apply a simulated compression artifact effect to images. This tool processes an input image to create a visual representation of blockiness and color quantization, which are common artifacts in lossy image compression. Users can adjust the block size and quantization factor to customize the effect. This tool can be particularly useful for digital artists and designers looking to create unique visual styles, for education on image compression techniques, or for individuals who want to give their images a retro or stylized appearance reminiscent of lower-quality compression methods.

Leave a Reply

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