Start · Sprachen · JavaScript · Referenz · OffscreenCanvas.transferToImageBitmap()

OffscreenCanvas.transferToImageBitmap()

Methode

Erzeugt aus dem zuletzt gerenderten Bild eines <code>OffscreenCanvas</code> ein <code>ImageBitmap</code> und setzt den Canvas-Inhalt dabei zurück.

seit JavaScript Baseline 2023: Chrome 69, Firefox 105, Safari 16.4 Kategorie: webapi

Signatur

OffscreenCanvas.prototype.transferToImageBitmap()

Beschreibung

transferToImageBitmap() nimmt den aktuellen Inhalt eines OffscreenCanvas und gibt ihn als ImageBitmap zurück. Die Methode arbeitet synchron. Die Bilddaten werden dabei nicht kopiert, sondern übertragen, deshalb ist sie sehr schnell. Das ist der wesentliche Unterschied zu createImageBitmap(), das eine Kopie anlegt und ein Promise zurückgibt.

Nach dem Aufruf bekommt der OffscreenCanvas einen neuen, leeren Zeichenpuffer. Bei 2D-Kontexten ist er transparent schwarz. Bei WebGL-Kontexten wird der Zeichenpuffer entsprechend den Kontextattributen geleert. Man zeichnet also jedes Bild neu und überträgt es danach.

Typischerweise nutzt man die Methode so: In einem Web Worker werden Bilder in einen OffscreenCanvas gerendert, der mit new OffscreenCanvas(w, h) erzeugt wurde. Jedes fertige Bild wird mit transferToImageBitmap() herausgelöst und per postMessage() als übertragbares Objekt an den Haupt-Thread geschickt. Dort zeigt ein <canvas> mit dem Kontext "bitmaprenderer" das Bild über transferFromImageBitmap() ohne Kopie an. So kann ein Worker auch mehrere sichtbare Canvas-Elemente beliefern.

Wurde der OffscreenCanvas dagegen über canvas.transferControlToOffscreen() erzeugt, erscheint sein Inhalt automatisch im zugehörigen <canvas>. Dann braucht man transferToImageBitmap() meist nicht.

Rückgabewert

Typ
ImageBitmap
Beschreibung
Ein neues ImageBitmap mit dem zuletzt gerenderten Bild. Breite und Höhe entsprechen dem OffscreenCanvas.

Beispiele

Einzelbild erzeugen und im Haupt-Thread anzeigen

// Offscreen zeichnen
const offscreen = new OffscreenCanvas(200, 100);
const ctx = offscreen.getContext('2d');
ctx.fillStyle = 'steelblue';
ctx.fillRect(0, 0, 200, 100);
ctx.fillStyle = 'white';
ctx.font = '20px sans-serif';
ctx.fillText('Hallo!', 60, 55);

// Bild herauslösen – der Offscreen-Puffer ist danach leer
const bitmap = offscreen.transferToImageBitmap();
console.log(bitmap.width, bitmap.height);

// Ohne Kopie in ein sichtbares Canvas übernehmen
const canvas = document.querySelector('#ausgabe');
const renderer = canvas.getContext('bitmaprenderer');
renderer.transferFromImageBitmap(bitmap);
200 100

Worker rendert, Haupt-Thread zeigt an

// worker.js
const offscreen = new OffscreenCanvas(300, 150);
const ctx = offscreen.getContext('2d');
let x = 0;

const render = () => {
  ctx.clearRect(0, 0, 300, 150);
  ctx.fillStyle = 'tomato';
  ctx.fillRect(x, 50, 50, 50);
  x = (x + 2) % 300;

  const bitmap = offscreen.transferToImageBitmap();
  // Als übertragbares Objekt senden (keine Kopie)
  self.postMessage({ bitmap }, [bitmap]);
  requestAnimationFrame(render); // in Workern: Chrome, Firefox
};
render();

// main.js
const worker = new Worker('worker.js');
const view = document.querySelector('canvas').getContext('bitmaprenderer');
worker.addEventListener('message', ({ data }) => {
  view.transferFromImageBitmap(data.bitmap);
});

Puffer wird nach dem Transfer zurückgesetzt

const oc = new OffscreenCanvas(1, 1);
const ctx = oc.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 1, 1);

console.log(ctx.getImageData(0, 0, 1, 1).data); // vorher
const bmp = oc.transferToImageBitmap();
console.log(ctx.getImageData(0, 0, 1, 1).data); // nachher
bmp.close(); // Speicher freigeben
Uint8ClampedArray [255, 0, 0, 255] Uint8ClampedArray [0, 0, 0, 0]

// Wichtig · Fallstricke

  • Der Canvas-Inhalt wird geleert: Nach dem Aufruf ist der Zeichenpuffer leer. Wer auf den bisherigen Inhalt aufbauen will, muss ihn neu zeichnen oder stattdessen createImageBitmap(offscreen) verwenden, das eine Kopie erzeugt.
  • Die Methode wirft einen InvalidStateError, wenn der Canvas noch keinen Rendering-Kontext hat (also getContext() nie aufgerufen wurde) oder wenn der Kontext "bitmaprenderer" ist.
  • Speicher: Ein ImageBitmap belegt Grafikspeicher. Nicht mehr benötigte Bitmaps sollte man mit bitmap.close() freigeben. transferFromImageBitmap() übernimmt die Bitmap und macht sie danach unbrauchbar. Beim Senden per postMessage sollte die Bitmap in der Transfer-Liste stehen, sonst wird sie kopiert.
  • Kompatibilität: OffscreenCanvas ist erst seit Safari 16.4 und Firefox 105 vollständig verfügbar. WebGL im Offscreen-Kontext unterstützt Safari erst ab Version 17. In Workern gibt es requestAnimationFrame nicht überall. Als Ersatz dient setTimeout.