Start · Sprachen · JavaScript · Referenz · ImageBitmap.close()

ImageBitmap.close()

Methode

Gibt alle grafischen Ressourcen eines <code>ImageBitmap</code> sofort frei; danach ist das Bitmap unbrauchbar und hat Breite und Höhe 0.

seit JavaScript Baseline: alle modernen Browser (Chrome 52+, Firef Kategorie: webapi

Signatur

ImageBitmap.prototype.close()

Beschreibung

close() gibt die Pixeldaten und den GPU- bzw. Grafikspeicher eines ImageBitmap sofort frei, statt auf den Garbage Collector zu warten. Das ist besonders wichtig, wenn viele Bitmaps kurz hintereinander entstehen, etwa bei Videoframe-Verarbeitung, Sprite-Animationen oder beim Laden großer Bildmengen in einem Worker.

Nach dem Aufruf gilt das Bitmap als detached (abgetrennt): width und height geben 0 zurück. Wird es dann noch an drawImage(), createImageBitmap() oder texImage2D() übergeben, wirft der Browser einen InvalidStateError (DOMException). Das JavaScript-Objekt existiert zwar weiter, ist aber nicht mehr nutzbar.

Rufe close() auf, sobald du ein Bitmap nicht mehr zeichnen musst, also typischerweise direkt nach dem letzten drawImage() oder nach dem Hochladen als WebGL-Textur. Mehrfaches Aufrufen ist unbedenklich; jeder weitere Aufruf bewirkt nichts.

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück.

Beispiele

Bitmap zeichnen und danach sofort freigeben

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

const response = await fetch('/bilder/foto.jpg');
const blob = await response.blob();
const bitmap = await createImageBitmap(blob);

ctx.drawImage(bitmap, 0, 0);
console.log(bitmap.width, bitmap.height);

bitmap.close(); // Speicher sofort freigeben
console.log(bitmap.width, bitmap.height);
1920 1080 0 0

Zugriff nach close() führt zu InvalidStateError

const canvas = new OffscreenCanvas(100, 100);
const ctx = canvas.getContext('2d');
const bitmap = await createImageBitmap(new ImageData(100, 100));

bitmap.close();

try {
  ctx.drawImage(bitmap, 0, 0);
} catch (err) {
  console.log(err.name);
}
InvalidStateError

Videoframes in einer Schleife verarbeiten ohne Speicherleck

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

const renderFrame = async () => {
  const frame = await createImageBitmap(video, { resizeWidth: 320, resizeHeight: 180 });
  ctx.drawImage(frame, 0, 0);
  frame.close(); // ohne close() würde der GPU-Speicher schnell volllaufen
  requestAnimationFrame(renderFrame);
};

video.addEventListener('play', () => requestAnimationFrame(renderFrame));

WebGL-Textur hochladen und Bitmap freigeben

const gl = document.querySelector('canvas').getContext('webgl2');
const blob = await (await fetch('/texturen/stein.png')).blob();
const bitmap = await createImageBitmap(blob, { imageOrientation: 'flipY' });

const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
gl.generateMipmap(gl.TEXTURE_2D);

// Daten liegen jetzt in der Textur, das Bitmap wird nicht mehr gebraucht
bitmap.close();

// Wichtig · Fallstricke

  • Nicht umkehrbar: Ein geschlossenes Bitmap lässt sich nicht wiederherstellen. Brauchst du das Bild später noch, erzeuge es neu mit createImageBitmap().
  • Übertragung an Worker: Wird ein ImageBitmap per postMessage(bitmap, [bitmap]) als Transferable übergeben, ist das Original im sendenden Kontext danach ebenfalls abgetrennt. Freigeben mit close() muss dann der Empfänger.
  • ImageBitmapRenderingContext: transferFromImageBitmap() übernimmt das Bitmap und trennt es ab. Ein zusätzliches close() ist dort nicht nötig.
  • Speicher: Ohne close() hält der Browser die Ressourcen, bis der Garbage Collector aufräumt. Bei hoher Bildrate kann das zu Speicherspitzen oder abgebrochenen GPU-Kontexten führen, vor allem auf Mobilgeräten.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt, auch in Web Workern. Safari unterstützt es erst ab Version 15.