You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, numSitesParam = 100, showSitesParam = "false", siteColorParam = "black", siteSizeParam = 2) {
// Parameter parsing and validation
let numSites;
if (typeof numSitesParam === 'string') {
numSites = parseInt(numSitesParam, 10);
} else {
numSites = numSitesParam; // Assumed to be a number as per guidelines
}
if (isNaN(numSites) || numSites <= 0) {
numSites = 100; // Default if parsing failed or invalid value
}
const showSites = String(showSitesParam).toLowerCase() === 'true';
let siteColor;
if (typeof siteColorParam === 'number') {
// Convert number to hex color string, e.g., 0xFF0000 -> "#ff0000"
const hex = (siteColorParam & 0xFFFFFF).toString(16).padStart(6, '0');
siteColor = `#${hex}`;
} else {
siteColor = String(siteColorParam); // Use as string (e.g., "red", "#FF0000")
}
let siteSize;
if (typeof siteSizeParam === 'string') {
siteSize = parseFloat(siteSizeParam);
} else {
siteSize = siteSizeParam; // Assumed to be a number
}
if (isNaN(siteSize) || siteSize <= 0) {
siteSize = 2; // Default if parsing failed or invalid value
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { willReadFrequently: true });
const w = originalImg.naturalWidth;
const h = originalImg.naturalHeight;
if (w === 0 || h === 0) {
console.error("Image not loaded or has invalid dimensions.");
// Return a 1x1 transparent canvas
canvas.width = 1;
canvas.height = 1;
ctx.clearRect(0, 0, 1, 1);
return canvas;
}
canvas.width = w;
canvas.height = h;
// Draw original image to the canvas to sample site colors
ctx.drawImage(originalImg, 0, 0, w, h);
const originalImageData = ctx.getImageData(0, 0, w, h);
const originalPixels = originalImageData.data;
const sites = [];
for (let i = 0; i < numSites; i++) {
const sx = Math.random() * w; // site x-coordinate
const sy = Math.random() * h; // site y-coordinate
// Get color from original image at site location (integer part of coordinates)
const ix = Math.floor(sx);
const iy = Math.floor(sy);
// Ensure ix and iy are within bounds, though Math.random()*dim should typically ensure this
const clampedIx = Math.max(0, Math.min(w - 1, ix));
const clampedIy = Math.max(0, Math.min(h - 1, iy));
const pixelIndex = (clampedIy * w + clampedIx) * 4;
const r = originalPixels[pixelIndex];
const g = originalPixels[pixelIndex + 1];
const b = originalPixels[pixelIndex + 2];
const a = originalPixels[pixelIndex + 3];
sites.push({ x: sx, y: sy, color: { r, g, b, a } });
}
// If for some reason no sites were generated (e.g., numSites became 0 due to bad parsing not caught by defaults)
// This check is mostly defensive as current logic ensures numSites >= 1.
if (sites.length === 0) {
// Draw original image and return if no sites.
ctx.drawImage(originalImg, 0, 0, w, h);
return canvas;
}
const outputImageData = ctx.createImageData(w, h);
const outputPixels = outputImageData.data;
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
let minDistSq = Infinity;
let closestSite = sites[0]; // Initialize with the first site, assumes sites.length > 0
for (const site of sites) {
const dx = x - site.x;
const dy = y - site.y;
const distSq = dx * dx + dy * dy; // Using squared distance for efficiency
if (distSq < minDistSq) {
minDistSq = distSq;
closestSite = site;
}
}
const pixelIndex = (y * w + x) * 4;
outputPixels[pixelIndex] = closestSite.color.r;
outputPixels[pixelIndex + 1] = closestSite.color.g;
outputPixels[pixelIndex + 2] = closestSite.color.b;
outputPixels[pixelIndex + 3] = closestSite.color.a; // Use alpha from the site's sampled color
}
}
ctx.putImageData(outputImageData, 0, 0); // Draw the Voronoi pattern
if (showSites) {
ctx.fillStyle = siteColor;
sites.forEach(site => {
ctx.beginPath();
ctx.arc(site.x, site.y, siteSize, 0, 2 * Math.PI);
ctx.fill();
});
}
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 Voronoi Filter Application allows users to create a unique Voronoi-patterned effect from an image. By specifying parameters such as the number of sites, the color and size of the sites, and whether to display the sites, users can transform their images into visually striking compositions. This tool is particularly useful for artists, designers, and anyone looking to explore creative variations of their images, adding an abstract and organized structure reminiscent of stained glass or mosaic art.