Please bookmark this page to avoid losing your image tool!

Image Mosaic Filter

(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, blockSize = 10) {
    // Sanitize blockSize: ensure it's an integer and at least 1
    blockSize = Math.max(1, Math.floor(blockSize));

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

    // Handle cases where image dimensions are invalid (e.g., image not loaded yet)
    if (imgWidth === 0 || imgHeight === 0) {
        const emptyCanvas = document.createElement('canvas');
        emptyCanvas.width = imgWidth; // will be 0
        emptyCanvas.height = imgHeight; // will be 0
        console.warn("Image Mosaic Filter: Image has zero width or height. Returning empty canvas.");
        return emptyCanvas;
    }

    // Create a source canvas to draw the original image.
    // This canvas is used internally to get pixel data and is not the final output.
    const srcCanvas = document.createElement('canvas');
    srcCanvas.width = imgWidth;
    srcCanvas.height = imgHeight;
    const srcCtx = srcCanvas.getContext('2d', { 
        // Hint for browser performance: we will be reading pixel data frequently.
        willReadFrequently: true 
    });
    srcCtx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);

    let imageData;
    try {
        // Get all pixel data from the source image at once for efficiency.
        imageData = srcCtx.getImageData(0, 0, imgWidth, imgHeight);
    } catch (e) {
        // This can happen if the canvas is tainted (e.g., cross-origin image without CORS headers).
        console.error("Image Mosaic Filter: Failed to getImageData. This might be due to a tainted canvas (cross-origin image). Returning original image on a new canvas.", e);
        // As a fallback, return the original image drawn on a new canvas.
        const fallbackCanvas = document.createElement('canvas');
        fallbackCanvas.width = imgWidth;
        fallbackCanvas.height = imgHeight;
        const fallbackCtx = fallbackCanvas.getContext('2d');
        fallbackCtx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
        return fallbackCanvas;
    }
    const data = imageData.data;

    // Create the destination canvas where the mosaic effect will be rendered.
    const destCanvas = document.createElement('canvas');
    destCanvas.width = imgWidth;
    destCanvas.height = imgHeight;
    const destCtx = destCanvas.getContext('2d');

    // Iterate over the image in blocks defined by blockSize.
    for (let y = 0; y < imgHeight; y += blockSize) {
        for (let x = 0; x < imgWidth; x += blockSize) {
            // Determine the actual width and height of the current block.
            // This handles edge cases where blockSize doesn't evenly divide image dimensions.
            const currentBlockW = Math.min(blockSize, imgWidth - x);
            const currentBlockH = Math.min(blockSize, imgHeight - y);

            let sumR = 0, sumG = 0, sumB = 0, sumA = 0;
            // Calculate the total number of pixels in the current block.
            const numPixelsInBlock = currentBlockW * currentBlockH;

            // This check is mostly a safeguard; numPixelsInBlock should be > 0 if imgWidth/Height > 0.
            if (numPixelsInBlock === 0) {
                continue;
            }

            // Iterate over each pixel within the current block to sum color values.
            for (let by = 0; by < currentBlockH; by++) { // by: y-coordinate relative to the block's top-left
                for (let bx = 0; bx < currentBlockW; bx++) { // bx: x-coordinate relative to the block's top-left
                    // Calculate the absolute x and y coordinates of the pixel in the overall image.
                    const pixelY = y + by;
                    const pixelX = x + bx;
                    
                    // Calculate the starting index of this pixel's data in the 1D imageData array.
                    // Each pixel is 4 array elements (R, G, B, A).
                    const index = (pixelY * imgWidth + pixelX) * 4;
                    
                    sumR += data[index];
                    sumG += data[index + 1];
                    sumB += data[index + 2];
                    sumA += data[index + 3];
                }
            }

            // Calculate the average color for the block.
            const avgR = Math.floor(sumR / numPixelsInBlock);
            const avgG = Math.floor(sumG / numPixelsInBlock);
            const avgB = Math.floor(sumB / numPixelsInBlock);
            const avgA = Math.floor(sumA / numPixelsInBlock);

            // Set the fill style to the calculated average color (including average alpha).
            // The alpha component for rgba() in CSS is a value between 0 (transparent) and 1 (opaque).
            destCtx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
            
            // Draw the colored block onto the destination canvas.
            destCtx.fillRect(x, y, currentBlockW, currentBlockH);
        }
    }

    return destCanvas;
}

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 Mosaic Filter is a tool that transforms images into a mosaic effect by dividing the image into blocks and replacing each block with an average color. This can be particularly useful for creating artistic effects in digital art, enhancing privacy in personal photos, or generating unique background images. Users can adjust the size of the blocks to customize the degree of the mosaic effect, making it suitable for various creative applications.

Leave a Reply

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