You can edit the below JavaScript code to customize the image tool.
Apply Changes
/**
* Creates a visual table (a "translation list") from an image sprite sheet of characters.
* Each character from the input string is mapped to a corresponding sprite from the image.
*
* @param {HTMLImageElement} originalImg The source image containing the character sprite sheet.
* @param {string} characters A string representing the characters in the sprite sheet, in order of appearance (left-to-right, top-to-bottom).
* @param {number} charWidth The width of a single character sprite in pixels.
* @param {number} charHeight The height of a single character sprite in pixels.
* @param {number} displayScale The scaling factor for displaying the character sprites in the output list.
* @param {number} columns The number of columns for the output table layout.
* @returns {HTMLCanvasElement} A canvas element displaying the character-to-sprite mapping table.
*/
function processImage(originalImg, characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?', charWidth = 8, charHeight = 8, displayScale = 3, columns = 8) {
// --- 1. Input Validation and Initial Setup ---
if (!originalImg || !characters || charWidth <= 0 || charHeight <= 0 || displayScale <= 0 || columns <= 0) {
console.error("Invalid parameters provided.");
const errorCanvas = document.createElement('canvas');
errorCanvas.width = 400;
errorCanvas.height = 50;
const ctx = errorCanvas.getContext('2d');
ctx.fillStyle = '#ffdddd';
ctx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
ctx.fillStyle = '#d8000c';
ctx.font = '16px monospace';
ctx.fillText('Error: Invalid parameters for processing.', 10, 30);
return errorCanvas;
}
// --- 2. Extract Character Sprites from the Image ---
const charMap = new Map();
const spriteSheetCols = Math.floor(originalImg.width / charWidth);
for (let i = 0; i < characters.length; i++) {
const char = characters[i];
const col = i % spriteSheetCols;
const row = Math.floor(i / spriteSheetCols);
const sx = col * charWidth;
const sy = row * charHeight;
// Ensure the character sprite is within the image bounds
if (sx + charWidth > originalImg.width || sy + charHeight > originalImg.height) {
console.warn(`Character '${char}' at index ${i} is outside the source image bounds. Skipping.`);
continue;
}
// Create a small canvas for each character to hold its sprite data
const charCanvas = document.createElement('canvas');
charCanvas.width = charWidth;
charCanvas.height = charHeight;
const charCtx = charCanvas.getContext('2d');
charCtx.drawImage(originalImg, sx, sy, charWidth, charHeight, 0, 0, charWidth, charHeight);
charMap.set(char, charCanvas);
}
if (charMap.size === 0) {
const errorCanvas = document.createElement('canvas');
errorCanvas.width = 400;
errorCanvas.height = 50;
const ctx = errorCanvas.getContext('2d');
ctx.fillStyle = '#ffdddd';
ctx.fillRect(0, 0, errorCanvas.width, errorCanvas.height);
ctx.fillStyle = '#d8000c';
ctx.font = '16px monospace';
ctx.fillText('Error: No valid characters found in image.', 10, 30);
return errorCanvas;
}
// --- 3. Calculate Dimensions for the Output Canvas ---
const fontHeight = 16;
const padding = 10;
// Calculate the maximum width of the text labels (e.g., "'W' -> ") to align the images
let maxLabelWidth = 0;
const tempCtx = document.createElement('canvas').getContext('2d');
tempCtx.font = `${fontHeight}px monospace`;
for (const char of charMap.keys()) {
const label = `'${char}' -> `;
const width = tempCtx.measureText(label).width;
if (width > maxLabelWidth) {
maxLabelWidth = width;
}
}
const cellWidth = maxLabelWidth + (charWidth * displayScale) + padding * 2;
const cellHeight = Math.max(fontHeight, charHeight * displayScale) + padding * 2;
const numRows = Math.ceil(charMap.size / columns);
const outputCanvas = document.createElement('canvas');
outputCanvas.width = columns * cellWidth;
outputCanvas.height = numRows * cellHeight;
const ctx = outputCanvas.getContext('2d');
// --- 4. Draw the Translation List onto the Output Canvas ---
// Use nearest-neighbor scaling to preserve the pixelated look
ctx.imageSmoothingEnabled = false;
// Draw background
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, outputCanvas.width, outputCanvas.height);
ctx.fillStyle = '#333333';
ctx.font = `${fontHeight}px monospace`;
ctx.textBaseline = 'middle';
let i = 0;
for (const [char, charCanvas] of charMap.entries()) {
const col = i % columns;
const row = Math.floor(i / columns);
const dx = col * cellWidth + padding;
const dy = row * cellHeight + (cellHeight / 2);
// Draw character label (e.g., "'A' -> ")
const label = `'${char}' -> `;
ctx.fillText(label, dx, dy);
// Draw the corresponding character sprite, scaled up
const imageX = dx + maxLabelWidth;
const imageY = dy - (charHeight * displayScale) / 2;
ctx.drawImage(charCanvas, imageX, imageY, charWidth * displayScale, charHeight * displayScale);
i++;
}
// --- 5. Return the final canvas ---
return outputCanvas;
}
Apply Changes