You can edit the below JavaScript code to customize the image tool.
async function processImage(
originalImg,
cellSize = 16,
lineColor = "rgba(0,255,0,0.75)", // Green, slightly transparent
lineWidth = 1,
backgroundColor = "rgba(0,20,0,1)", // Dark green
lineProbability = 0.7,
nodeProbability = 0.3,
nodeSize = 2, // Absolute size in pixels (width/height of square node)
useImageBrightness = 1, // 0 for no, 1 for yes
brightnessInfluence = 0.7 // 0-1, how much brightness affects probabilities
) {
const outputCanvas = document.createElement('canvas');
outputCanvas.width = originalImg.width;
outputCanvas.height = originalImg.height;
const outputCtx = outputCanvas.getContext('2d');
// Fill background
outputCtx.fillStyle = backgroundColor;
outputCtx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
// Set line and node style (nodes will use same color as lines)
outputCtx.strokeStyle = lineColor;
outputCtx.lineWidth = lineWidth;
outputCtx.fillStyle = lineColor; // Nodes will use the same color
let tempCanvas, tempCtx;
if (useImageBrightness === 1) {
tempCanvas = document.createElement('canvas');
tempCanvas.width = originalImg.width;
tempCanvas.height = originalImg.height;
tempCtx = tempCanvas.getContext('2d');
// Draw the original image to the temporary canvas to read its pixel data
tempCtx.drawImage(originalImg, 0, 0);
}
// Helper function to get average brightness (0-1) of a block from a canvas context
function getAverageBrightness(ctx, x, y, w, h, imgWidth, imgHeight) {
const sx = Math.max(0, Math.floor(x));
const sy = Math.max(0, Math.floor(y));
const ex = Math.min(imgWidth, Math.ceil(x + w)); // End x, exclusive
const ey = Math.min(imgHeight, Math.ceil(y + h)); // End y, exclusive
const clampedW = ex - sx;
const clampedH = ey - sy;
if (clampedW <= 0 || clampedH <= 0) {
return 0.5; // Default brightness for out-of-bounds or zero-size area
}
const imageData = ctx.getImageData(sx, sy, clampedW, clampedH);
const data = imageData.data;
let rSum = 0, gSum = 0, bSum = 0;
for (let i = 0; i < data.length; i += 4) {
rSum += data[i];
gSum += data[i + 1];
bSum += data[i + 2];
}
const numPixels = data.length / 4;
if (numPixels === 0) {
return 0.5; // Default if no pixels (should be caught by clampedW/H check)
}
const avgIntensity = (rSum / numPixels + gSum / numPixels + bSum / numPixels) / 3;
return avgIntensity / 255; // Normalize to 0-1 range
}
// Determine the number of grid points based on canvas size and cell size
const numXPoints = Math.floor(outputCanvas.width / cellSize) + 1;
const numYPoints = Math.floor(outputCanvas.height / cellSize) + 1;
for (let r = 0; r < numYPoints; r++) {
for (let c = 0; c < numXPoints; c++) {
const currentX = c * cellSize;
const currentY = r * cellSize;
// Skip points that are entirely outside the drawable canvas width/height
// (only relevant for the last point if width/height not multiple of cellSize)
if (currentX > outputCanvas.width && currentY > outputCanvas.height) continue;
let cellBrightness = 0.5; // Default brightness (e.g., if not using image brightness)
if (useImageBrightness === 1 && tempCtx) {
// Brightness is sampled from the cell area starting at (currentX, currentY)
// and extending cellSize x cellSize to its South-East.
cellBrightness = getAverageBrightness(tempCtx, currentX, currentY, cellSize, cellSize, originalImg.width, originalImg.height);
}
let brightnessModifier = 1.0;
if (useImageBrightness === 1) {
// Lerp between 1 (no influence) and cellBrightness based on brightnessInfluence
// modifier = (1 - influence) * 1.0 + influence * cellBrightness
brightnessModifier = (1.0 - brightnessInfluence) + brightnessInfluence * cellBrightness;
}
const finalLineProbability = lineProbability * brightnessModifier;
const finalNodeProbability = nodeProbability * brightnessModifier;
// Draw a node at the current grid point (currentX, currentY)
if (Math.random() < finalNodeProbability) {
// Centering the node square on (currentX, currentY)
outputCtx.fillRect(currentX - nodeSize / 2, currentY - nodeSize / 2, nodeSize, nodeSize);
}
// Begin path for potential lines from this point
outputCtx.beginPath();
// Attempt to draw a horizontal line to the right
if (c < numXPoints - 1) { // Ensure there's a point to the right
if (currentX + cellSize <= outputCanvas.width) { // And the line is within canvas bounds
if (Math.random() < finalLineProbability) {
outputCtx.moveTo(currentX, currentY);
outputCtx.lineTo(currentX + cellSize, currentY);
}
}
}
// Attempt to draw a vertical line downwards
if (r < numYPoints - 1) { // Ensure there's a point below
if (currentY + cellSize <= outputCanvas.height) { // And the line is within canvas bounds
if (Math.random() < finalLineProbability) {
outputCtx.moveTo(currentX, currentY);
outputCtx.lineTo(currentX, currentY + cellSize);
}
}
}
outputCtx.stroke(); // Draw the lines (if any) added to the current path
}
}
return outputCanvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Microchip Pattern Filter Effect tool applies a grid-like pattern to images, simulating a microchip aesthetic. Users can customize parameters such as cell size, line and node colors, line width, and the influence of the image’s brightness on the pattern. This tool is useful for creating abstract art, enhancing digital designs, or giving images a unique technological look suitable for various applications, including graphic design, branding, and artistic projects.