You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, blockSizeStr = "10") {
let blockSize = parseInt(blockSizeStr); // Handles string or number input for blockSizeStr
if (isNaN(blockSize) || blockSize <= 0) {
blockSize = 10; // Default value if input is invalid or non-positive
}
blockSize = Math.floor(blockSize); // Ensure blockSize is an integer for pixel operations
const width = originalImg.naturalWidth;
const height = originalImg.naturalHeight;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
// Handle cases where the image might not be loaded or is invalid (0 dimensions)
if (width === 0 || height === 0) {
console.warn("Image has zero width or height. Returning an empty canvas.");
// An empty canvas of 0x0 (or Wx0, 0xH) is returned, which is appropriate.
// Could draw an error explicitly, but an empty canvas for empty input is logical.
return canvas;
}
const ctx = canvas.getContext('2d');
if (!ctx) {
console.error("Failed to get 2D context from canvas. Returning an empty canvas of original dimensions.");
// Cannot draw an error message without a context. The canvas will be blank.
return canvas;
}
try {
// Draw the original image onto the canvas. This canvas will serve as both the
// source for reading pixel data (from the original image parts) and the
// destination for writing the mosaic blocks.
ctx.drawImage(originalImg, 0, 0, width, height);
// Iterate over the image in blocks based on blockSize
for (let y = 0; y < height; y += blockSize) {
for (let x = 0; x < width; x += blockSize) {
// Determine the actual dimensions of the current block,
// handling edge cases where the block might be smaller than blockSize
// (e.g., at the right or bottom edge of the image).
const currentBlockWidth = Math.min(blockSize, width - x);
const currentBlockHeight = Math.min(blockSize, height - y);
// Ensure block dimensions are valid before proceeding.
// This should generally not be an issue given the loop conditions (y < height, x < width).
if (currentBlockWidth <= 0 || currentBlockHeight <= 0) {
continue;
}
// Get pixel data for the current block from the canvas.
// At this point, this part of the canvas contains the original image's pixels.
const imageData = ctx.getImageData(x, y, currentBlockWidth, currentBlockHeight);
const data = imageData.data; // RGBA array for the block
let sumR = 0, sumG = 0, sumB = 0, sumA = 0;
const numPixelsInBlock = currentBlockWidth * currentBlockHeight;
// This check should also be redundant if currentBlockWidth/Height > 0.
if (numPixelsInBlock === 0) continue;
// Calculate the sum of R, G, B, A values for all pixels in the block
for (let i = 0; i < data.length; i += 4) {
sumR += data[i]; // Red
sumG += data[i+1]; // Green
sumB += data[i+2]; // Blue
sumA += data[i+3]; // Alpha
}
// Calculate the average R, G, B, A values for the block
const avgR = Math.round(sumR / numPixelsInBlock);
const avgG = Math.round(sumG / numPixelsInBlock);
const avgB = Math.round(sumB / numPixelsInBlock);
const avgA = Math.round(sumA / numPixelsInBlock);
// Set the fill style to the calculated average color of the block
ctx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
// Draw the rectangle with the average color over the current block region.
// This action overwrites the original image pixels in this block,
// effectively creating the mosaic tile.
ctx.fillRect(x, y, currentBlockWidth, currentBlockHeight);
}
}
} catch (e) {
console.error("Error during image processing in processImage:", e);
// If an error occurs (e.g., CORS issue with getImageData),
// create and return a new canvas displaying an error message.
const errorCanvas = document.createElement('canvas');
// Use original image dimensions for the error canvas, or defaults if original dimensions were 0.
errorCanvas.width = width > 0 ? width : 300;
errorCanvas.height = height > 0 ? height : 150;
const errorCtx = errorCanvas.getContext('2d');
if (errorCtx) {
// Draw a background for the error message
errorCtx.fillStyle = '#FEE'; // A light, noticeable color like light yellow/pink
errorCtx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
// Style and draw the main error message
errorCtx.font = 'bold 16px Arial';
errorCtx.fillStyle = '#D00'; // Dark red for high visibility
errorCtx.textAlign = 'center';
errorCtx.textBaseline = 'middle';
let message = 'Error processing image.';
if (e.name === 'SecurityError') { // Handle common SecurityError for cross-origin issues
message = 'Cannot process: Image source is cross-origin restricted.';
}
errorCtx.fillText(message, errorCanvas.width / 2, errorCanvas.height / 2 - 10);
// Add a sub-message with the specific error name and message for debugging aid
errorCtx.font = '12px Arial';
errorCtx.fillStyle = '#333'; // Dark gray for sub-text
const detailMessage = `(${e.name || 'Error'}: ${e.message || 'Details unavailable'})`;
errorCtx.fillText(detailMessage, errorCanvas.width / 2, errorCanvas.height / 2 + 12);
} else {
// If context for errorCanvas also fails (very rare),
// return the original canvas (which might be blank or partially processed).
console.error("Failed to get context for error canvas as well.");
return canvas;
}
return errorCanvas; // Return the canvas with the error message drawn on it
}
// Return the canvas with the mosaic effect applied
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Mosaic Filter Application enables users to transform their images into customizable mosaic artwork. By adjusting the block size, users can create varied mosaic effects, from fine details to bold, larger color blocks. This tool is ideal for graphic designers, artists, and social media enthusiasts looking to enhance their visuals with a unique artistic touch. It can be used for creating personalized gifts, designing promotional materials, or simply exploring creative expression through digital art.