Start · Sprachen · JavaScript · Referenz · GPUQueue.copyExternalImageToTexture()

GPUQueue.copyExternalImageToTexture()

Methode

Kopiert einen Schnappschuss aus einem Bild, Video, Canvas, <code>ImageBitmap</code> oder <code>VideoFrame</code> direkt in eine <code>GPUTexture</code>.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPUQueue.prototype.copyExternalImageToTexture(source, destination, copySize)

Beschreibung

copyExternalImageToTexture() ist in WebGPU der bequemste Weg, Bilddaten aus dem Browser in eine Textur zu übertragen. Im Gegensatz zu GPUQueue.writeTexture() muss man die Pixel nicht selbst als ArrayBuffer dekodieren. Der Browser übernimmt Dekodierung, Umrechnung des Farbraums, optional die Vormultiplikation des Alphakanals und das vertikale Spiegeln.

Als Quelle sind ImageBitmap, ImageData, HTMLImageElement, HTMLVideoElement, VideoFrame, HTMLCanvasElement und OffscreenCanvas erlaubt. Kopiert wird immer der aktuelle Zustand der Quelle. Bei Videos ist das das gerade angezeigte Bild. Für laufende Videos muss man die Methode deshalb in jedem Frame erneut aufrufen. Alternativ kann man mit GPUDevice.importExternalTexture() ohne Kopie arbeiten.

Der Aufruf wird wie alle Queue-Operationen in die Warteschlange der GPU eingereiht und kehrt sofort zurück. Validierungsfehler, etwa ein falsches Texturformat oder fehlende Usage-Flags, landen im Fehlermechanismus von WebGPU (pushErrorScope() bzw. das Event uncapturederror). Nur Fehler an der Quelle selbst werden synchron als Ausnahme geworfen.

Parameter

Name Typ Default Beschreibung
$source Pflicht GPUCopyExternalImageSourceInfo Objekt mit der Quelle:
  • source (Pflicht): ImageBitmap | ImageData | HTMLImageElement | HTMLVideoElement | VideoFrame | HTMLCanvasElement | OffscreenCanvas
  • origin: GPUOrigin2D, Startpunkt in der Quelle, Standard {x: 0, y: 0}
  • flipY: boolean, spiegelt das Bild vertikal, Standard false
$destination Pflicht GPUCopyExternalImageDestInfo Ziel der Kopie:
  • texture (Pflicht): die Ziel-GPUTexture
  • mipLevel: Standard 0
  • origin: GPUOrigin3D, Standard {} (also 0,0,0)
  • aspect: Standard "all"
  • colorSpace: "srgb" oder "display-p3", Standard "srgb"
  • premultipliedAlpha: boolean, Standard false
$copySize Pflicht GPUExtent3D Größe des kopierten Bereichs, als Array [width, height, depthOrArrayLayers] oder als Objekt { width, height, depthOrArrayLayers }. depthOrArrayLayers muss 1 sein.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Die Kopie wird in die Warteschlange der GPU eingereiht.

Beispiele

Bild laden und in eine Textur kopieren

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const response = await fetch('/img/stein.png');
const bitmap = await createImageBitmap(await response.blob(), {
  colorSpaceConversion: 'none'
});

const texture = device.createTexture({
  size: [bitmap.width, bitmap.height],
  format: 'rgba8unorm',
  // COPY_DST und RENDER_ATTACHMENT sind Pflicht
  usage: GPUTextureUsage.TEXTURE_BINDING |
         GPUTextureUsage.COPY_DST |
         GPUTextureUsage.RENDER_ATTACHMENT
});

device.queue.copyExternalImageToTexture(
  { source: bitmap, flipY: false },
  { texture },
  [bitmap.width, bitmap.height]
);

bitmap.close(); // Speicher der Bitmap freigeben
console.log('Textur:', texture.width, 'x', texture.height);
Textur: 512 x 512

Jedes Videobild in eine Textur übertragen

const video = document.querySelector('video');
await video.play();

const videoTexture = device.createTexture({
  size: [video.videoWidth, video.videoHeight],
  format: 'rgba8unorm',
  usage: GPUTextureUsage.TEXTURE_BINDING |
         GPUTextureUsage.COPY_DST |
         GPUTextureUsage.RENDER_ATTACHMENT
});

const onFrame = () => {
  // Schnappschuss des aktuellen Videobilds
  device.queue.copyExternalImageToTexture(
    { source: video },
    { texture: videoTexture },
    [video.videoWidth, video.videoHeight]
  );
  // ... hier rendern ...
  video.requestVideoFrameCallback(onFrame);
};
video.requestVideoFrameCallback(onFrame);

Ausschnitt eines Canvas mit Fehlerbehandlung kopieren

const canvas = new OffscreenCanvas(256, 256);
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(0, 0, 256, 256);

const atlas = device.createTexture({
  size: [1024, 1024],
  format: 'rgba8unorm',
  usage: GPUTextureUsage.TEXTURE_BINDING |
         GPUTextureUsage.COPY_DST |
         GPUTextureUsage.RENDER_ATTACHMENT
});

device.pushErrorScope('validation');
try {
  device.queue.copyExternalImageToTexture(
    { source: canvas, origin: { x: 64, y: 64 } },
    { texture: atlas, origin: { x: 512, y: 0 }, premultipliedAlpha: true },
    { width: 128, height: 128 }
  );
} catch (err) {
  // z. B. SecurityError bei Cross-Origin-Quelle
  console.error(err.name, err.message);
}
const gpuError = await device.popErrorScope();
console.log(gpuError ? gpuError.message : 'Kopie erfolgreich');
Kopie erfolgreich