Canvas Basics for Text Rendering
The HTML5 Canvas provides a 2D drawing surface that you control pixel by pixel. Unlike DOM-based text rendering, canvas gives you absolute control over glyph placement, anti-aliasing (or lack thereof), and pixel dimensions. This makes it ideal for creating dense, deterministic text images.
Creating a Bitmap Font Atlas
A bitmap font atlas is a lookup table mapping each character to a fixed-size pixel grid. For a 5×8 atlas, each character is represented by 40 binary values indicating which pixels should be inked. This is fundamentally different from vector fonts — there are no curves, no hinting, and no subpixel rendering.
Stamping Characters onto Canvas
The rendering loop iterates character by character. For each character, it looks up the atlas entry, calculates the target (x, y) position based on column and row counters, and writes the pixel data to the canvas using putImageData or individual fillRect calls. The result is a perfectly grid-aligned text layout.
Exporting as PNG
Once all characters are stamped, call canvas.toDataURL('image/png') to produce a Base64-encoded PNG string. This string can be downloaded as a file, displayed in an img element, or sent directly to an LLM API as an image attachment.
Optimization Techniques
Batch pixel writes using ImageData buffers instead of individual fillRect calls. Pre-compute atlas positions into a typed array for faster lookup. Use OffscreenCanvas for web worker rendering. These optimizations let you render 1 million characters in under 2 seconds.
Minimal Bitmap Text Renderer
// Minimal 5x8 bitmap text renderer
function renderText(text, cols = 200) {
const CHAR_W = 5, CHAR_H = 8;
const lines = [];
let currentLine = '';
for (const ch of text) {
if (ch === '\n' || currentLine.length >= cols) {
lines.push(currentLine);
currentLine = ch === '\n' ? '' : ch;
} else {
currentLine += ch;
}
}
if (currentLine) lines.push(currentLine);
const canvas = document.createElement('canvas');
canvas.width = cols * CHAR_W;
canvas.height = lines.length * CHAR_H;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
lines.forEach((line, row) => {
[...line].forEach((ch, col) => {
stampGlyph(ctx, ch, col * CHAR_W, row * CHAR_H);
});
});
return canvas.toDataURL('image/png');
}
Frequently Asked Questions
Conclusion
Visual token encoding is a practical, immediately deployable optimization that works with your existing AI stack. Whether you are a developer building pipelines or a founder managing API budgets, the ~88% input cost reduction compounds into real savings that improve your margins and extend your runway.
Ready to try it? Open PXINK and drop a file to see your savings instantly.