Signatur
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
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);
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);
}
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
ImageBitmapperpostMessage(bitmap, [bitmap])als Transferable übergeben, ist das Original im sendenden Kontext danach ebenfalls abgetrennt. Freigeben mitclose()muss dann der Empfänger. - ImageBitmapRenderingContext:
transferFromImageBitmap()übernimmt das Bitmap und trennt es ab. Ein zusätzlichesclose()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.