You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, beadSizeParam = 10, outlineColor = 'rgba(0,0,0,0.3)', outlineWidthParam = 1) {
let beadSize = Number(beadSizeParam);
let outlineWidth = Number(outlineWidthParam);
// Validate parameters
if (isNaN(beadSize) || beadSize <= 0) {
console.warn(`Invalid beadSize: ${beadSizeParam}. Using default 10.`);
beadSize = 10;
}
if (isNaN(outlineWidth) || outlineWidth < 0) {
console.warn(`Invalid outlineWidth: ${outlineWidthParam}. Using default 1.`);
outlineWidth = 1;
}
if (typeof outlineColor !== 'string') {
console.warn(`Invalid outlineColor type. Using default 'rgba(0,0,0,0.3)'.`);
outlineColor = 'rgba(0,0,0,0.3)';
}
const outputCanvas = document.createElement('canvas');
// Check if originalImg is valid and has dimensions
if (!originalImg || typeof originalImg.width !== 'number' || typeof originalImg.height !== 'number' || originalImg.width === 0 || originalImg.height === 0) {
console.error("Original image is invalid or has zero dimensions.");
// Set canvas to a small size or 0x0 if image info is totally missing
outputCanvas.width = (originalImg && typeof originalImg.width === 'number') ? originalImg.width : 50;
outputCanvas.height = (originalImg && typeof originalImg.height === 'number') ? originalImg.height : 50;
if (outputCanvas.width === 0 || outputCanvas.height === 0) {
outputCanvas.width = 50; outputCanvas.height = 50; // Ensure some drawable area
}
const errorCtx = outputCanvas.getContext('2d');
errorCtx.fillStyle = 'lightgray';
errorCtx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
errorCtx.fillStyle = 'red';
errorCtx.font = '12px Arial';
errorCtx.textAlign = 'center';
errorCtx.textBaseline = 'middle';
errorCtx.fillText('Invalid Image', outputCanvas.width / 2, outputCanvas.height / 2);
return outputCanvas;
}
outputCanvas.width = originalImg.width;
outputCanvas.height = originalImg.height;
const ctx = outputCanvas.getContext('2d');
// Create a temporary canvas to get pixel data from the original image
const sourceCanvas = document.createElement('canvas');
sourceCanvas.width = originalImg.width;
sourceCanvas.height = originalImg.height;
const sourceCtx = sourceCanvas.getContext('2d', { willReadFrequently: true }); // Hint for optimization
try {
sourceCtx.drawImage(originalImg, 0, 0, originalImg.width, originalImg.height);
} catch (e) {
console.error("Error drawing original image to source canvas:", e);
ctx.fillStyle = 'lightgray';
ctx.fillRect(0,0, outputCanvas.width, outputCanvas.height);
ctx.fillStyle = 'red';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Error: Could not draw original image.', outputCanvas.width / 2, outputCanvas.height / 2);
return outputCanvas;
}
let imageData;
try {
imageData = sourceCtx.getImageData(0, 0, originalImg.width, originalImg.height);
} catch (e) {
// This typically happens due to CORS issues if the image is from a different origin
// and the server doesn't provide appropriate CORS headers.
console.error("Error getting image data (likely CORS issue):", e);
ctx.fillStyle = 'lightgray';
ctx.fillRect(0,0, outputCanvas.width, outputCanvas.height);
ctx.fillStyle = 'red';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Error: Cannot access image pixels (CORS?).', outputCanvas.width / 2, outputCanvas.height / 2);
return outputCanvas;
}
const data = imageData.data;
// Iterate over the image in blocks of beadSize x beadSize
for (let y = 0; y < originalImg.height; y += beadSize) {
for (let x = 0; x < originalImg.width; x += beadSize) {
let rSum = 0, gSum = 0, bSum = 0, aSum = 0;
let numPixelsInBlock = 0;
// Determine the actual width and height of the current block for averaging,
// important for blocks near the image edges.
const currentBlockWidth = Math.min(beadSize, originalImg.width - x);
const currentBlockHeight = Math.min(beadSize, originalImg.height - y);
// Calculate the average color of the block
for (let blockPixelY = 0; blockPixelY < currentBlockHeight; blockPixelY++) {
for (let blockPixelX = 0; blockPixelX < currentBlockWidth; blockPixelX++) {
// Calculate the coordinates of the pixel in the original image
const sourcePixelX = x + blockPixelX;
const sourcePixelY = y + blockPixelY;
// Calculate the index in the 1D pixel data array
const pixelIndex = (sourcePixelY * originalImg.width + sourcePixelX) * 4;
rSum += data[pixelIndex]; // Red
gSum += data[pixelIndex + 1]; // Green
bSum += data[pixelIndex + 2]; // Blue
aSum += data[pixelIndex + 3]; // Alpha
numPixelsInBlock++;
}
}
if (numPixelsInBlock > 0) {
const avgR = Math.floor(rSum / numPixelsInBlock);
const avgG = Math.floor(gSum / numPixelsInBlock);
const avgB = Math.floor(bSum / numPixelsInBlock);
const avgA = Math.floor(aSum / numPixelsInBlock);
// Center of the bead for this grid cell
const beadCenterX = x + beadSize / 2;
const beadCenterY = y + beadSize / 2;
// Radius of the colored part of the bead
const radius = beadSize / 2;
if (radius > 0) { // Only draw if bead has some size
// Draw the fill (colored part) of the bead
ctx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
ctx.beginPath(); // Start a new path for this bead
ctx.arc(beadCenterX, beadCenterY, radius, 0, 2 * Math.PI);
ctx.fill();
// Draw the outline of the bead if specified
if (outlineWidth > 0 && outlineColor && outlineColor !== 'transparent') {
ctx.strokeStyle = outlineColor;
ctx.lineWidth = outlineWidth;
// The arc path is already defined from the fill, so we just stroke it.
ctx.stroke();
}
}
}
}
}
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 Native American Beadwork Filter Effect Tool allows users to transform their images into a unique artistic style reminiscent of Native American beadwork. By adjusting parameters such as bead size, outline color, and outline width, users can create visually appealing renditions of their images that mimic the appearance of beads arranged on a canvas. This tool can be useful for artists, designers, and anyone looking to create custom artwork, craft project materials, or personalized gifts with a distinct cultural flair.