You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, ledSize = 8, spacing = 2, ledShape = "circle") {
// Validate parameters
ledSize = Math.max(1, Number(ledSize)); // Ensure ledSize is at least 1
spacing = Math.max(0, Number(spacing)); // Ensure spacing is non-negative
if (typeof ledShape !== 'string' || (ledShape.toLowerCase() !== "circle" && ledShape.toLowerCase() !== "square")) {
ledShape = "circle"; // Default to circle if invalid shape or type given
} else {
ledShape = ledShape.toLowerCase(); // Normalize to lowercase for consistent checking
}
const outputCanvas = document.createElement('canvas');
const ctx = outputCanvas.getContext('2d');
// Check if originalImg is a valid, loaded image object.
// A loaded HTMLImageElement/Image object will have width and height > 0.
if (!originalImg ||
typeof originalImg.width !== 'number' ||
typeof originalImg.height !== 'number' ||
originalImg.width === 0 ||
originalImg.height === 0) {
// If image is not loaded or dimensions are zero, return a minimal 1x1 canvas.
outputCanvas.width = 1;
outputCanvas.height = 1;
// Optionally, you could fill this 1x1 canvas with a specific color
// ctx.fillStyle = 'rgba(0,0,0,0.1)';
// ctx.fillRect(0,0,1,1);
return outputCanvas;
}
outputCanvas.width = originalImg.width;
outputCanvas.height = originalImg.height;
// Draw the original image onto the canvas. This is step 1 to get pixel data.
ctx.drawImage(originalImg, 0, 0, outputCanvas.width, outputCanvas.height);
let imageData;
try {
// Get pixel data from the drawn image.
imageData = ctx.getImageData(0, 0, outputCanvas.width, outputCanvas.height);
} catch (e) {
// This error can occur if the canvas is "tainted", usually due to cross-origin image issues.
console.error("Error getting ImageData:", e);
// In case of error, we can return the canvas with an error message.
// Clear canvas (it might have parts of original image if drawImage succeeded partially before error)
ctx.fillStyle = '#FFFFFF'; // White background for error message
ctx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
ctx.fillStyle = '#FF0000'; // Red text color for error
ctx.font = "bold 16px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Error: Cannot process image.", outputCanvas.width / 2, outputCanvas.height / 2 - 10);
ctx.font = "14px Arial";
ctx.fillText("May be due to CORS policy.", outputCanvas.width / 2, outputCanvas.height / 2 + 10);
return outputCanvas;
}
const data = imageData.data; // Uint8ClampedArray [R,G,B,A, R,G,B,A, ...]
// Clear the canvas and set the background color for the LED grid (the "unlit" part of the screen).
ctx.fillStyle = '#000000'; // Black background, common for LED screens
ctx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
// cellSize is the dimension of one "LED cell", which includes the LED itself and its surrounding spacing.
const cellSize = ledSize + spacing;
// Iterate over the image in blocks of cellSize x cellSize.
for (let y = 0; y < outputCanvas.height; y += cellSize) {
for (let x = 0; x < outputCanvas.width; x += cellSize) {
let sumR = 0, sumG = 0, sumB = 0, sumA = 0;
let count = 0;
// Define the actual region to sample from the original image for this LED.
// This handles partial cells at the image edges.
const sampleBoxYStart = y;
const sampleBoxXStart = x;
const sampleBoxYEnd = Math.min(y + cellSize, outputCanvas.height);
const sampleBoxXEnd = Math.min(x + cellSize, outputCanvas.width);
// Calculate the average color of the pixels in this region.
for (let py = sampleBoxYStart; py < sampleBoxYEnd; py++) {
for (let px = sampleBoxXStart; px < sampleBoxXEnd; px++) {
const M_idx = (py * outputCanvas.width + px) * 4; // Index in the imageData array
sumR += data[M_idx];
sumG += data[M_idx + 1];
sumB += data[M_idx + 2];
sumA += data[M_idx + 3]; // Include alpha in averaging
count++;
}
}
if (count > 0) {
const avgR = Math.round(sumR / count);
const avgG = Math.round(sumG / count);
const avgB = Math.round(sumB / count);
const avgA = Math.round(sumA / count);
// Set fill style for the LED with the averaged color and alpha.
ctx.fillStyle = `rgba(${avgR}, ${avgG}, ${avgB}, ${avgA / 255})`;
// Calculate the top-left position for drawing the LED shape.
// The LED (size `ledSize`) is centered within its cell (size `cellSize`).
// The offset from the cell's top-left (x,y) is (cellSize - ledSize) / 2.
// Since cellSize = ledSize + spacing, this offset is (spacing / 2).
const ledDrawX = x + spacing / 2;
const ledDrawY = y + spacing / 2;
if (ledShape === "circle") {
ctx.beginPath();
ctx.arc(
ledDrawX + ledSize / 2, // centerX of the circle
ledDrawY + ledSize / 2, // centerY of the circle
ledSize / 2, // radius of the circle
0, // startAngle (0 radians)
2 * Math.PI // endAngle (360 degrees)
);
ctx.fill();
} else { // "square"
ctx.fillRect(ledDrawX, ledDrawY, ledSize, ledSize);
}
}
}
}
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 LED Screen Filter Effect Tool is designed to transform images into a stylized representation that mimics the look of an LED screen. Users can specify the size, spacing, and shape of the ‘LEDs’ used in the effect, allowing for customization of the final output. This tool can be utilized for creating eye-catching graphics for digital displays, social media, or web projects, providing a unique visual aesthetic reminiscent of pixelated LED displays.