Start · Sprachen · JavaScript · Referenz · ImageCapture

ImageCapture

Schnittstelle

Nimmt Standbilder und Einzelbilder von einer Kamera auf, deren Videospur als <code>MediaStreamTrack</code> vorliegt, und liest Foto-Fähigkeiten und -Einstellungen aus.

seit JavaScript Chromium-Browser (Chrome/Edge/Opera 59+); nicht in Kategorie: webapi

Signatur

interface ImageCapture

Beschreibung

ImageCapture gehört zur MediaStream Image Capture API. Das Objekt wird mit einer Video-Spur (MediaStreamTrack mit kind === "video") erzeugt, die man meist über navigator.mediaDevices.getUserMedia() bekommt. Damit lassen sich echte Fotos in voller Sensorauflösung aufnehmen – oft deutlich höher als die Auflösung des laufenden Videostreams.

Wichtige Mitglieder:

  • new ImageCapture(videoTrack) – Konstruktor.
  • track – schreibgeschützt; die übergebene MediaStreamTrack.
  • takePhoto(photoSettings?) – gibt ein Promise<Blob> mit einem kodierten Foto zurück (z. B. JPEG). Optional können imageWidth, imageHeight, fillLightMode und redEyeReduction übergeben werden.
  • grabFrame() – gibt ein Promise<ImageBitmap> mit dem aktuellen Videoeinzelbild zurück. Das geht schnell, hat aber nur die Stream-Auflösung.
  • getPhotoCapabilities() – gibt ein Promise<PhotoCapabilities> zurück (unterstützte Bildgrößen, Blitz-Modi, Rote-Augen-Reduktion).
  • getPhotoSettings() – gibt ein Promise<PhotoSettings> mit den aktuellen Einstellungen zurück.

Die Schnittstelle eignet sich zum Beispiel für Dokumentenscanner, Profilfoto-Aufnahmen, Barcode-Vorverarbeitung oder Zeitraffer-Aufnahmen. Kamerafunktionen wie Zoom, Fokus oder Taschenlampe werden dagegen nicht über ImageCapture eingestellt, sondern über track.applyConstraints() und track.getCapabilities().

Parameter

Name Typ Default Beschreibung
$videoTrack Pflicht MediaStreamTrack Konstruktor-Argument: eine Video-Spur, etwa aus stream.getVideoTracks()[0]. Ist kind nicht "video", wird ein NotSupportedError (DOMException) geworfen.
$photoSettings { imageWidth?: number, imageHeight?: number, fillLightMode?: "auto"|"off"|"flash", redEyeReduction?: boolean } {} Optionales Argument für takePhoto(). Die Werte müssen innerhalb der Bereiche liegen, die getPhotoCapabilities() meldet.

Rückgabewert

Typ
ImageCapture
Beschreibung
Eine neue ImageCapture-Instanz, die fest an die übergebene Video-Spur gebunden ist.

Beispiele

Instanz erzeugen und Foto als Blob aufnehmen

const takeSnapshot = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
  const [track] = stream.getVideoTracks();
  const imageCapture = new ImageCapture(track);

  const blob = await imageCapture.takePhoto();
  console.log(`Foto: ${blob.type}, ${blob.size} Bytes`);

  // Vorschau anzeigen
  const img = document.querySelector('#photo');
  img.src = URL.createObjectURL(blob);
  img.onload = () => URL.revokeObjectURL(img.src);

  track.stop(); // Kamera freigeben
};

document.querySelector('#shoot').addEventListener('click', takeSnapshot);
Foto: image/jpeg, 482311 Bytes

Einzelbild mit grabFrame() auf ein Canvas zeichnen

const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 1280, height: 720 } });
const imageCapture = new ImageCapture(stream.getVideoTracks()[0]);

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

const bitmap = await imageCapture.grabFrame();
canvas.width = bitmap.width;
canvas.height = bitmap.height;
ctx.drawImage(bitmap, 0, 0);
bitmap.close(); // Speicher sofort freigeben

console.log(`Frame: ${canvas.width}x${canvas.height}`);
Frame: 1280x720

Fähigkeiten abfragen und in maximaler Auflösung mit Blitz fotografieren

const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });
const imageCapture = new ImageCapture(stream.getVideoTracks()[0]);

const caps = await imageCapture.getPhotoCapabilities();
console.log('Breite:', caps.imageWidth.min, '–', caps.imageWidth.max);
console.log('Blitz-Modi:', caps.fillLightMode);

const settings = {
  imageWidth: caps.imageWidth.max,
  imageHeight: caps.imageHeight.max,
  ...(caps.fillLightMode.includes('flash') && { fillLightMode: 'flash' })
};

try {
  const blob = await imageCapture.takePhoto(settings);
  console.log('Aufgenommen:', blob.size, 'Bytes');
} catch (err) {
  console.error('Aufnahme fehlgeschlagen:', err.name, err.message);
}
Breite: 320 – 4032 Blitz-Modi: ["auto", "off", "flash"] Aufgenommen: 2873410 Bytes

Feature-Erkennung mit Canvas-Fallback

const captureFrame = async (video) => {
  const track = video.srcObject.getVideoTracks()[0];
  if ('ImageCapture' in window) {
    return new ImageCapture(track).grabFrame();
  }
  // Fallback für Firefox/Safari: aktuelles Videobild über ein Canvas holen
  const canvas = new OffscreenCanvas(video.videoWidth, video.videoHeight);
  canvas.getContext('2d').drawImage(video, 0, 0);
  return createImageBitmap(canvas);
};

const video = document.querySelector('video');
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
await video.play();
const frame = await captureFrame(video);
console.log(frame.width, frame.height);
640 480

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Unterstützt wird die Schnittstelle nur in Chromium-Browsern (Chrome, Edge, Opera, Samsung Internet). Firefox und Safari kennen ImageCapture nicht. Prüfe daher immer vorher mit 'ImageCapture' in window und sieh einen Canvas-Fallback vor.
  • Sicherer Kontext und Berechtigung: getUserMedia() funktioniert nur über HTTPS oder localhost und nur mit Kamera-Freigabe durch die Nutzerin oder den Nutzer. In iframes ist außerdem allow="camera" nötig.
  • Beendete Spur: Wurde track.stop() aufgerufen oder ist track.readyState gleich "ended", werden takePhoto() und grabFrame() mit InvalidStateError abgelehnt. Eine stummgeschaltete oder deaktivierte Spur (enabled = false) führt ebenfalls zu Fehlern.
  • Parallele Aufrufe: Mehrere gleichzeitige takePhoto()-Aufrufe können mit OperationError fehlschlagen. Warte deshalb jeden Aufruf per await ab, bevor du den nächsten startest.
  • Nebenwirkungen: Unter Umständen stellt takePhoto() die Kamera kurz um, sodass der Videostream stockt oder die Belichtung springt. Für schnelle Serienbilder ist grabFrame() besser geeignet.
  • Speicher: ImageBitmap-Objekte mit close() und Objekt-URLs mit URL.revokeObjectURL() freigeben.
  • Zoom, Fokus, Belichtung und Taschenlampe (torch) werden über MediaStreamTrack.applyConstraints() gesteuert, nicht über photoSettings.