Canvas + Pretext advanced design 75% Usefulness

Text-zu-Bild ASCII-Art Generator mit Canvas und Text-Messung

Erstelle ASCII-Art aus Videos, indem du Text-Zeichen auf ein Raster legst und die Helligkeit von Video-Pixeln nutzt, um festzulegen, welche Zeichen angezeigt werden.

Originalvideo ansehen: He just crawled through hell to fix the browser…
4 Schritte
1

Character-Grid mit Text-Messung erstellen

Nutze Pretext, um ein Raster zu erstellen, bei dem jede Cell genau ein Character enthält

const script = 'Dein langer Text...'; // Die ASCII-Art Zeichen
const segments = pretext.prepare(script, { font: '10px monospace' });

const characterGrid = [];
let charIndex = 0;

for (let row = 0; row < totalRows; row++) {
  const layoutInfo = pretext.layout(segments, { width: containerWidth });
  // Jede Row entspricht einer Zeile im Video
  characterGrid[row] = script.substring(charIndex, charIndex + layoutInfo.charsPerLine);
  charIndex += layoutInfo.charsPerLine;
}
Tipp: Verwende Monospace-Font für gleichmäßiges Raster
Warnung: Character-Count pro Zeile ändert sich mit Font-Größe
2

Video auf offscreen Canvas zeichnen und Pixel auslesen

Zeichne das Video auf ein Canvas-Element derselben Größe wie das Character-Grid und lese die Helligkeit aus

const offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = characterGrid[0].length * charWidth;
offscreenCanvas.height = characterGrid.length * charHeight;
const offscreenCtx = offscreenCanvas.getContext('2d');

// Video-Frame zeichnen
offscreenCtx.drawImage(videoElement, 0, 0, offscreenCanvas.width, offscreenCanvas.height);

// Pixel-Daten auslesen
const imageData = offscreenCtx.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
const pixelData = imageData.data; // RGBA-Array
Tipp: Canvas sollte genau die Größe des Character-Grids haben
Warnung: getImageData() ist synchron und kann langsam sein bei großen Canvas
3

Pixel-Helligkeit pro Character-Cell berechnen

Für jede Cell im Grid, berechne die durchschnittliche Helligkeit der entsprechenden Pixel

function getPixelBrightness(pixelData, x, y, pixelIndex) {
  const r = pixelData[pixelIndex];
  const g = pixelData[pixelIndex + 1];
  const b = pixelData[pixelIndex + 2];
  // Luminosity-Formel
  return 0.299 * r + 0.587 * g + 0.114 * b;
}

const brightnessGrid = [];
for (let row = 0; row < characterGrid.length; row++) {
  brightnessGrid[row] = [];
  for (let col = 0; col < characterGrid[row].length; col++) {
    const pixelX = col * charWidth;
    const pixelY = row * charHeight;
    const pixelIndex = (pixelY * offscreenCanvas.width + pixelX) * 4;
    brightnessGrid[row][col] = getPixelBrightness(pixelData, pixelX, pixelY, pixelIndex);
  }
}
Tipp: Luminosity-Formel besser als einfacher Durchschnitt für menschliches Auge
Warnung: Performance kritisch; erwäge WebWorker für große Grids
4

Characters basierend auf Helligkeit rendern

Zeige nur Characters an, wenn die entsprechenden Pixel hell genug sind

const brightnessThreshold = 128; // Schwellenwert anpassen
const finalHTML = characterGrid.map((row, rowIndex) => {
  return row.split('').map((char, colIndex) => {
    const brightness = brightnessGrid[rowIndex][colIndex];
    if (brightness > brightnessThreshold) {
      return `<span style="color: rgb(${brightness}, ${brightness}, ${brightness})">${char}</span>`;
    }
    return '<span>&nbsp;</span>'; // Leerer Platz
  }).join('');
}).join('<br>');

document.getElementById('output').innerHTML = finalHTML;
Tipp: Variantentext-Helligkeitswerte für Graustufeneffekte
Warnung: Zu niedriger Threshold = unlesbares Chaos; zu hoch = keine Details
← Alle Playbooks anzeigen