Start · Sprachen · JavaScript · Referenz · ImageTrack

ImageTrack

Schnittstelle

Das <code>ImageTrack</code>-Interface der WebCodecs API steht für eine einzelne Bildspur eines <code>ImageDecoder</code> und liefert Informationen wie Animation, Frame-Anzahl und Wiederholungen.

seit JavaScript Chromium 94+, Firefox 133+; Safari: nicht unterstü Kategorie: webapi

Signatur

interface ImageTrack

Beschreibung

Ein ImageTrack beschreibt eine einzelne Spur innerhalb einer Bilddatei, die ein ImageDecoder dekodiert. Die meisten Formate (JPEG, PNG, GIF) haben genau eine Spur. Container-Formate wie AVIF können aber mehrere Spuren enthalten, etwa ein Standbild und eine animierte Sequenz.

Einen ImageTrack erzeugt man nicht selbst, es gibt also keinen öffentlichen Konstruktor. Man bekommt ihn über die ImageTrackList in decoder.tracks, entweder per Index (tracks[0]) oder über tracks.selectedTrack. Bevor man zugreift, sollte man auf das Promise tracks.ready warten.

Eigenschaften:

  • animated (boolean, nur lesbar): true, wenn die Spur mehr als einen Frame zur Animation enthält.
  • frameCount (number, nur lesbar): Anzahl der Frames in der Spur. Bei gestreamten Daten kann der Wert zunächst zu niedrig sein und später steigen.
  • repetitionCount (number, nur lesbar): Wie oft die Animation wiederholt wird. 0 heißt: einmal abspielen, Infinity heißt: Endlosschleife.
  • selected (boolean, les- und schreibbar): Gibt an, ob die Spur gerade zum Dekodieren ausgewählt ist. Setzt man den Wert auf true, wird diese Spur aktiv und die bisher gewählte abgewählt.

Man nutzt ImageTrack vor allem, um animierte Bilder (GIF, animiertes WebP/PNG, AVIF) Frame für Frame zu verarbeiten, z. B. um sie selbst auf einem <canvas> abzuspielen, Vorschaubilder zu erzeugen oder Frames in einem Worker zu verarbeiten.

Rückgabewert

Typ
ImageTrack
Beschreibung
Man bekommt Instanzen über ImageDecoder.tracks (eine ImageTrackList), z. B. decoder.tracks.selectedTrack oder decoder.tracks[i].

Beispiele

Spur-Informationen eines animierten GIFs auslesen

const response = await fetch('/img/animation.gif');
const decoder = new ImageDecoder({
  data: response.body,
  type: 'image/gif'
});

// Warten, bis die Spuren bekannt sind
await decoder.tracks.ready;
const track = decoder.tracks.selectedTrack;

// Bei Streams erst nach vollständigem Laden die endgültige Frame-Anzahl
await decoder.completed;

console.log('Animiert:', track.animated);
console.log('Frames:', track.frameCount);
console.log('Wiederholungen:', track.repetitionCount);
Animiert: true Frames: 24 Wiederholungen: Infinity

Animation Frame für Frame auf ein Canvas zeichnen

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const playAnimation = async (url) => {
  const res = await fetch(url);
  const decoder = new ImageDecoder({ data: res.body, type: res.headers.get('Content-Type') });
  await decoder.completed;

  const track = decoder.tracks.selectedTrack;
  const loops = track.repetitionCount === Infinity ? 3 : track.repetitionCount + 1;

  for (let loop = 0; loop < loops; loop++) {
    for (let i = 0; i < track.frameCount; i++) {
      const { image } = await decoder.decode({ frameIndex: i });
      ctx.drawImage(image, 0, 0);
      // duration ist in Mikrosekunden angegeben
      await new Promise((r) => setTimeout(r, (image.duration ?? 100000) / 1000));
      image.close(); // Speicher freigeben!
    }
  }
  decoder.close();
};

playAnimation('/img/animation.webp');

Zwischen mehreren Spuren wählen (z. B. AVIF)

if (!('ImageDecoder' in window)) {
  console.warn('WebCodecs ImageDecoder wird nicht unterstützt');
} else {
  const res = await fetch('/img/multi-track.avif');
  const decoder = new ImageDecoder({ data: res.body, type: 'image/avif' });
  await decoder.tracks.ready;

  // Erste animierte Spur suchen und auswählen
  const animatedTrack = Array.from(decoder.tracks).find((t) => t.animated);
  if (animatedTrack && !animatedTrack.selected) {
    animatedTrack.selected = true;
  }

  console.log('Spuren:', decoder.tracks.length);
  console.log('Gewählter Index:', decoder.tracks.selectedIndex);
}
Spuren: 2 Gewählter Index: 1

// Wichtig · Fallstricke

  • Browser-Unterstützung: ImageDecoder/ImageTrack gibt es in Chromium-Browsern ab Version 94 und in Firefox ab 133. Safari unterstützt sie bislang nicht. Deshalb vorher mit 'ImageDecoder' in window prüfen und eine Alternative vorsehen, etwa <img> oder createImageBitmap().
  • Nur in einem sicheren Kontext (HTTPS) verfügbar, auch in Dedicated Workern.
  • frameCount ist bei Streams (ReadableStream als data) anfangs unter Umständen unvollständig. Erst nach await decoder.completed ist der Wert endgültig.
  • Wer selected ändert, setzt den Decoder für die neue Spur zurück. Laufende decode()-Aufrufe können dann mit einem Fehler abgelehnt werden.
  • Es ist immer nur eine Spur gleichzeitig ausgewählt. selected = false auf der aktiven Spur hebt die Auswahl ganz auf (selectedIndex wird -1).
  • Die dekodierten VideoFrame-Objekte immer mit close() freigeben, sonst drohen Speicherlecks.
  • Ob ein Format unterstützt wird, lässt sich vorab mit ImageDecoder.isTypeSupported(type) prüfen.