Start · Sprachen · JavaScript · Referenz · new ImageDecoder()

new ImageDecoder()

Methode

Erstellt ein <code>ImageDecoder</code>-Objekt, das kodierte Bilddaten (z. B. PNG, JPEG, GIF, WebP, AVIF) entpackt und einzelne Frames als <code>VideoFrame</code> dekodiert.

seit JavaScript WebCodecs API – Chrome/Edge 94+, Firefox 133+; Saf Kategorie: webapi

Signatur

new ImageDecoder(init)

Beschreibung

Der Konstruktor ImageDecoder() gehört zur WebCodecs API. Er erzeugt einen Dekoder für kodierte Bilddaten, die entweder vollständig als ArrayBuffer/TypedArray oder schrittweise als ReadableStream vorliegen. Anders als ein <img>-Element oder createImageBitmap() gibt er dir direkten Zugriff auf einzelne Frames, Spuren (Tracks) und Metadaten wie Frame-Anzahl und Wiederholungszahl animierter Bilder.

Typische Einsatzfälle sind das frameweise Verarbeiten animierter GIFs oder WebPs, das Dekodieren in einem Web Worker ohne DOM, progressives Rendern während des Downloads sowie das Weiterreichen der Frames an Canvas, WebGL/WebGPU oder einen VideoEncoder.

Der Konstruktor selbst dekodiert noch nichts. Nach der Erzeugung wartest du auf decoder.tracks.ready bzw. decoder.completed und rufst dann decoder.decode({ frameIndex }) auf. Das Ergebnis enthält ein VideoFrame, das du nach Gebrauch mit close() freigeben musst. Ob ein Format unterstützt wird, prüfst du vorab mit der statischen Methode ImageDecoder.isTypeSupported().

Parameter

Name Typ Default Beschreibung
$init Pflicht Object Konfigurationsobjekt mit den folgenden Eigenschaften.
$init.type Pflicht string MIME-Typ der Bilddaten, z. B. "image/png", "image/gif", "image/webp". Wird der Typ nicht unterstützt, schlägt tracks.ready fehl.
$init.data Pflicht ArrayBuffer | TypedArray | DataView | ReadableStream Die kodierten Bilddaten – als vollständiger Puffer oder als Byte-Stream (z. B. response.body).
$init.premultiplyAlpha "default" | "none" | "premultiply" "default" Legt fest, ob Farbkanäle mit dem Alphakanal vormultipliziert werden.
$init.colorSpaceConversion "default" | "none" "default" Bei "none" werden eingebettete Farbprofile ignoriert und keine Farbraumkonvertierung durchgeführt.
$init.desiredWidth number Gewünschte Ausgabebreite. Nur zusammen mit desiredHeight gültig; hilfreich bei Formaten mit mehreren Auflösungen (z. B. ICO).
$init.desiredHeight number Gewünschte Ausgabehöhe. Nur zusammen mit desiredWidth gültig.
$init.preferAnimation boolean Bei Formaten mit mehreren Spuren: true wählt bevorzugt die animierte Spur als Anfangsspur.
$init.transfer ArrayBuffer[] [] Liste von ArrayBuffern, die ohne Kopie an den Dekoder übertragen (und dabei im Aufrufer detached) werden.

Rückgabewert

Typ
ImageDecoder
Beschreibung
Ein neues ImageDecoder-Objekt mit den Eigenschaften type, complete, completed und tracks sowie den Methoden decode(), reset() und close().

Beispiele

Erstes Frame eines PNG dekodieren und auf ein Canvas zeichnen

const response = await fetch('/bilder/logo.png');
const buffer = await response.arrayBuffer();

const decoder = new ImageDecoder({ type: 'image/png', data: buffer });

const { image } = await decoder.decode(); // frameIndex 0
const canvas = document.querySelector('canvas');
canvas.width = image.displayWidth;
canvas.height = image.displayHeight;
canvas.getContext('2d').drawImage(image, 0, 0);

console.log(`${image.displayWidth}×${image.displayHeight}`);
image.close();   // VideoFrame freigeben
decoder.close(); // Dekoder freigeben
256×256

Animiertes GIF per Stream laden und Frames abspielen

const type = 'image/gif';
if (!(await ImageDecoder.isTypeSupported(type))) {
  throw new Error('GIF wird nicht unterstützt');
}

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

await decoder.tracks.ready;
const track = decoder.tracks.selectedTrack;
await decoder.completed; // warten, bis alle Daten geladen sind
console.log('Frames:', track.frameCount, 'Wiederholungen:', track.repetitionCount);

const ctx = document.querySelector('canvas').getContext('2d');
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();
}
decoder.close();
Frames: 24 Wiederholungen: Infinity

Puffer ohne Kopie übertragen und Fehler abfangen

const buffer = await (await fetch('/foto.webp')).arrayBuffer();

try {
  const decoder = new ImageDecoder({
    type: 'image/webp',
    data: buffer,
    transfer: [buffer],        // Zero-Copy-Übergabe
    colorSpaceConversion: 'none'
  });
  console.log(buffer.byteLength); // Puffer ist jetzt detached
  const { image } = await decoder.decode();
  console.log(image.format, image.codedWidth);
  image.close();
  decoder.close();
} catch (err) {
  console.error('Dekodierung fehlgeschlagen:', err.name, err.message);
}
0 RGBA 1920