You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, facetSize = 10) {
const width = originalImg.width;
const height = originalImg.height;
const outputCanvas = document.createElement('canvas');
outputCanvas.width = width;
outputCanvas.height = height;
const ctx = outputCanvas.getContext('2d');
if (width === 0 || height === 0) {
return outputCanvas; // Return empty canvas if image is empty
}
// Use a temporary canvas to get pixel data from the original image
const tempCanvas = document.createElement('canvas');
tempCanvas.width = width;
tempCanvas.height = height;
// Add { willReadFrequently: true } for potential performance optimization if supported
const tempCtx = tempCanvas.getContext('2d', { willReadFrequently: true });
tempCtx.drawImage(originalImg, 0, 0, width, height);
let imageData;
try {
imageData = tempCtx.getImageData(0, 0, width, height);
} catch (e) {
// Handle potential security error if image is cross-origin and canvas is tainted
console.error("Image Diamond Facet Filter: Error getting image data - ", e);
// Fallback: draw original image on the output canvas if processing fails
ctx.drawImage(originalImg, 0, 0, width, height);
return outputCanvas;
}
const pixels = imageData.data;
// Sanitize facetSize:
// It represents the "radius" of the diamond (distance from center to North/South/East/West vertex).
let numFacetSize = parseFloat(String(facetSize));
if (isNaN(numFacetSize)) {
numFacetSize = 10; // Default value if facetSize is not a valid number
}
const r = Math.max(1, numFacetSize); // Ensure radius is at least 1 (e.g. facetSize=0 maps to r=1)
// Iterate for diamond centers.
// y values are y-coordinates of diamond centers. Loop step is r.
for (let y = 0; y < height + r; y += r) {
// Determine the row index for staggering. y/r should ideally be an integer.
// Math.round handles potential floating point inaccuracies if r or y are not perfect multiples.
const rowIndex = Math.round(y / r);
const isStaggeredRow = (rowIndex % 2 !== 0);
// x values are base points for calculating diamond centerX. Loop step is 2*r.
// Adjust startXLoop to ensure diamonds on the left edge are covered.
// Non-staggered rows start effectively "more to the left" to make space for a diamond centered near x=0.
const startXLoop = isStaggeredRow ? 0 : -r;
for (let x = startXLoop; x < width + r; x += 2 * r) {
// Calculate actual center of the current diamond
const centerX = x + r; // This adjustment makes centerX sequence like 0, 2r, 4r... or r, 3r, 5r...
const centerY = y;
// Calculate average color of pixels within this diamond's area
let rSum = 0, gSum = 0, bSum = 0, aSum = 0;
let count = 0;
// Define the bounding box of pixels to check.
// These are pixel indices, so they should be integers.
// Iterate through pixels whose centers *might* be in the diamond.
const minPx = Math.max(0, Math.floor(centerX - r));
const maxPx = Math.min(width, Math.ceil(centerX + r)); // Iterate up to, but not including, maxPx
const minPy = Math.max(0, Math.floor(centerY - r));
const maxPy = Math.min(height, Math.ceil(centerY + r)); // Iterate up to, but not including, maxPy
for (let py = minPy; py < maxPy; py++) {
for (let px = minPx; px < maxPx; px++) {
// Test if the center of the pixel (px + 0.5, py + 0.5) is inside the diamond.
// A point (ptX, ptY) is inside a diamond centered at (diamCx, diamCy) with radius diamR if:
// |ptX - diamCx| + |ptY - diamCy| <= diamR
const pixelCenterX = px + 0.5;
const pixelCenterY = py + 0.5;
if (Math.abs(pixelCenterX - centerX) + Math.abs(pixelCenterY - centerY) <= r) {
const index = (py * width + px) * 4;
rSum += pixels[index];
gSum += pixels[index + 1];
bSum += pixels[index + 2];
aSum += pixels[index + 3];
count++;
}
}
}
if (count > 0) {
const avgR = Math.round(rSum / count);
const avgG = Math.round(gSum / count);
const avgB = Math.round(bSum / count);
const avgA = Math.round(aSum / count); // Calculate average alpha
ctx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
// Draw the diamond
ctx.beginPath();
ctx.moveTo(centerX, centerY - r); // Top vertex
ctx.lineTo(centerX + r, centerY); // Right vertex
ctx.lineTo(centerX, centerY + r); // Bottom vertex
ctx.lineTo(centerX - r, centerY); // Left vertex
ctx.closePath();
ctx.fill();
}
}
}
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 Diamond Facet Filter Effect Tool allows users to apply a unique diamond facet filter effect to their images. By specifying a facet size, users can create visually striking effects that resemble sparkling diamonds, enhancing the aesthetics of photos. This tool is useful for artists, designers, and hobbyists looking to create eye-catching graphics for social media, presentations, or personal projects, turning regular images into vibrant art pieces.