You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&?", fontSize = 10) {
// Ensure originalImg is a usable Image object (basic check)
if (!originalImg || typeof originalImg.naturalWidth === 'undefined' || typeof originalImg.naturalHeight === 'undefined') {
console.error("processImage: Invalid originalImg object provided.");
const errCanvas = document.createElement('canvas');
errCanvas.width = 300;
errCanvas.height = 150;
const errCtx = errCanvas.getContext('2d');
if (errCtx) {
// Simple error display on the canvas
errCtx.fillStyle = '#F0F0F0'; // Light gray background
errCtx.fillRect(0, 0, errCanvas.width, errCanvas.height);
errCtx.fillStyle = '#333333'; // Dark gray text
errCtx.font = '16px Arial';
errCtx.textAlign = 'center';
errCtx.textBaseline = 'middle';
errCtx.fillText('Error: Invalid image input.', errCanvas.width / 2, errCanvas.height / 2);
}
return errCanvas;
}
// Validate and set default parameters
const effectiveCharSet = (typeof charSet === 'string' && charSet.length > 0) ? charSet : "01";
let numFontSize = Number(fontSize);
if (isNaN(numFontSize) || numFontSize <= 0) {
numFontSize = 10; // Default font size if invalid
}
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
// Handle cases where image might not be loaded or has no dimensions
if (imgWidth === 0 || imgHeight === 0) {
const emptyCanvas = document.createElement('canvas');
emptyCanvas.width = Math.max(1, imgWidth); // Ensure at least 1x1
emptyCanvas.height = Math.max(1, imgHeight);
return emptyCanvas;
}
// Create a temporary canvas to draw the original image and get its pixel data
const tempCanvas = document.createElement('canvas');
tempCanvas.width = imgWidth;
tempCanvas.height = imgHeight;
const tempCtx = tempCanvas.getContext('2d');
if (!tempCtx) {
console.error("processImage: Could not get 2D context from temporary canvas.");
const errCanvas = document.createElement('canvas');
errCanvas.width = imgWidth; errCanvas.height = imgHeight;
const errCtx = errCanvas.getContext('2d');
if (errCtx) {
errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
errCtx.fillText('Error: Canvas context failed (temp).', imgWidth / 2, imgHeight / 2);
}
return errCanvas;
}
tempCtx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
let imageData;
try {
imageData = tempCtx.getImageData(0, 0, imgWidth, imgHeight);
} catch (e) {
console.error("processImage: Error getting imageData (possibly CORS issue):", e);
const errCanvas = document.createElement('canvas');
errCanvas.width = imgWidth; errCanvas.height = imgHeight;
const errCtx = errCanvas.getContext('2d');
if (errCtx) {
errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
errCtx.fillText('Error: Cannot access image pixels.', imgWidth / 2, imgHeight / 2 - 10);
errCtx.fillText('(Possibly cross-origin image)', imgWidth / 2, imgHeight / 2 + 10);
}
return errCanvas;
}
const data = imageData.data;
// Create the output canvas
const outputCanvas = document.createElement('canvas');
outputCanvas.width = imgWidth;
outputCanvas.height = imgHeight;
const ctx = outputCanvas.getContext('2d');
if (!ctx) {
console.error("processImage: Could not get 2D context from output canvas.");
const errCanvas = document.createElement('canvas');
errCanvas.width = imgWidth; errCanvas.height = imgHeight;
const errCtx = errCanvas.getContext('2d');
if (errCtx) {
errCtx.fillStyle = '#F0F0F0'; errCtx.fillRect(0, 0, imgWidth, imgHeight);
errCtx.fillStyle = '#333333'; errCtx.font = '16px Arial';
errCtx.textAlign = 'center'; errCtx.textBaseline = 'middle';
errCtx.fillText('Error: Canvas context failed (output).', imgWidth / 2, imgHeight / 2);
}
return errCanvas;
}
// Set text properties for drawing characters
// Using monospace font ensures characters align somewhat in a grid
ctx.font = `${numFontSize}px monospace`;
ctx.textAlign = 'left'; // Characters drawn from top-left of their "cell"
ctx.textBaseline = 'top';
// Iterate over the image in a grid pattern based on fontSize
for (let y = 0; y < imgHeight; y += numFontSize) {
for (let x = 0; x < imgWidth; x += numFontSize) {
// Determine the center of the current cell to sample a pixel color
const sampleX = Math.min(Math.floor(x + numFontSize / 2), imgWidth - 1);
const sampleY = Math.min(Math.floor(y + numFontSize / 2), imgHeight - 1);
// Get RGBA components of the sampled pixel
const pixelIndex = (sampleY * imgWidth + sampleX) * 4;
const r = data[pixelIndex];
const g = data[pixelIndex + 1];
const b = data[pixelIndex + 2];
const a = data[pixelIndex + 3];
// If the sampled pixel's alpha is very low, skip drawing a character
// This helps preserve transparency from the original image.
// A_THRESHOLD (e.g., 25 means alpha < ~10%)
const ALPHA_THRESHOLD = 25;
if (a < ALPHA_THRESHOLD) {
continue;
}
// Select a random character from the provided character set
const charIndex = Math.floor(Math.random() * effectiveCharSet.length);
const char = effectiveCharSet[charIndex];
// Set the fill style (color and alpha) for the character
// to match the sampled pixel from the original image.
ctx.fillStyle = `rgba(${r},${g},${b},${a / 255})`;
// Draw the character at the top-left of the current grid cell
ctx.fillText(char, x, y);
}
}
return outputCanvas;
}
Apply Changes