Fotos aufnehmen und Kameraeinstellungen anpassen

Miguel Casas-Sanchez
François Beaufort
François Beaufort

Die Bilderfassung ist eine API zum Aufnehmen von Standbildern und Konfigurieren der Kamerahardwareeinstellungen. Diese API ist in Chrome 59 auf Android-Geräten und Computern verfügbar. Außerdem haben wir eine ImageCapture-Polyfill-Bibliothek veröffentlicht.

Die API ermöglicht die Steuerung von Kamerafunktionen wie Zoom, Helligkeit, Kontrast, ISO und Weißabgleich. Das Beste daran ist, dass Sie mit der Bilderfassung die volle Auflösung jeder verfügbaren Kamera oder Webcam Ihres Geräts nutzen können. Bisherige Methoden zum Aufnehmen von Fotos im Web nutzten Video-Snapshots, die eine geringere Auflösung als Standbilder haben.

Ein ImageCapture-Objekt wird mit einem MediaStreamTrack als Quelle erstellt. Die API hat dann zwei Aufnahmemethoden, takePhoto() und grabFrame(), und Möglichkeiten, die Funktionen und Einstellungen der Kamera abzurufen und zu ändern.

Baustelle

Die Image Capture API erhält Zugriff auf eine Kamera über eine MediaStreamTrack, die von getUserMedia() abgerufen wird:

navigator.mediaDevices.getUserMedia({video: true})
    .then(gotMedia)
    .catch(error => console.error('getUserMedia() error:', error));

function gotMedia(mediaStream) {
    const mediaStreamTrack = mediaStream.getVideoTracks()[0];
    const imageCapture = new ImageCapture(mediaStreamTrack);
    console.log(imageCapture);
}

Sie können diesen Code in der DevTools-Konsole ausprobieren.

Aufnehmen

Es gibt zwei Möglichkeiten, Fotos aufzunehmen: Vollbild und Schnellaufnahme. takePhoto() gibt einen Blob zurück, das Ergebnis einer einzelnen Belichtung, der heruntergeladen, vom Browser gespeichert oder in einem <img>-Element angezeigt werden kann. Bei dieser Methode wird die höchste verfügbare Auflösung der Fotokamera verwendet. Beispiel:

const img = document.querySelector('img');
// ...
imageCapture.takePhoto()
    .then(blob => {
    img.src = URL.createObjectURL(blob);
    img.onload = () => { URL.revokeObjectURL(this.src); }
    })
    .catch(error => console.error('takePhoto() error:', error));

grabFrame() gibt ein ImageBitmap-Objekt zurück, einen Snapshot des Live-Videos, der beispielsweise auf einem <canvas> gezeichnet und dann nachbearbeitet werden kann, um die Farbwerte selektiv zu ändern. Hinweis: Die ImageBitmap hat nur die Auflösung der Videoquelle, die in der Regel niedriger ist als die der Kamera für Standbilder. Beispiel:

const canvas = document.querySelector('canvas');
// ...
imageCapture.grabFrame()
    .then(imageBitmap => {
    canvas.width = imageBitmap.width;
    canvas.height = imageBitmap.height;
    canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
    })
    .catch(error => console.error('grabFrame() error:', error));

Funktionen und Einstellungen

Es gibt verschiedene Möglichkeiten, die Aufnahmeeinstellungen zu ändern. Das hängt davon ab, ob die Änderungen in der MediaStreamTrack berücksichtigt werden oder erst nach takePhoto() sichtbar sind. Eine Änderung des zoom-Levels wird beispielsweise sofort an den MediaStreamTrack weitergegeben, während die Rote-Augen-Reduzierung, wenn sie festgelegt ist, nur beim Aufnehmen des Fotos angewendet wird.

Die Funktionen und Einstellungen der „Live“-Kamera werden über die Vorschau MediaStreamTrack gesteuert: MediaStreamTrack.getCapabilities() gibt ein MediaTrackCapabilities-Wörterbuch mit den unterstützten Funktionen und den Bereichen oder zulässigen Werten zurück, z.B. den unterstützten Zoombereich oder die zulässigen Weißabgleichsmodi. Entsprechend gibt MediaStreamTrack.getSettings() ein MediaTrackSettings mit den aktuellen Einstellungen zurück. Zoom, Helligkeit und Taschenlampenmodus gehören beispielsweise zu dieser Kategorie:

var zoomSlider = document.querySelector('input[type=range]');
// ...
const capabilities = mediaStreamTrack.getCapabilities();
const settings = mediaStreamTrack.getSettings();
if (capabilities.zoom) {
    zoomSlider.min = capabilities.zoom.min;
    zoomSlider.max = capabilities.zoom.max;
    zoomSlider.step = capabilities.zoom.step;
    zoomSlider.value = settings.zoom;
}

Kamerafunktionen und ‑einstellungen, die nicht für Livestreams verfügbar sind, werden über das ImageCapture-Objekt gesteuert: ImageCapture.getPhotoCapabilities() gibt ein PhotoCapabilities-Objekt zurück, das Zugriff auf die verfügbaren Kamerafunktionen bietet, die nicht für Livestreams verfügbar sind. Ab Chrome 61 gibt ImageCapture.getPhotoSettings() ein PhotoSettings-Objekt mit den aktuellen Einstellungen zurück. Zu diesem Abschnitt gehören beispielsweise die Fotoauflösung, die Reduzierung von roten Augen und der Blitzmodus (außer Taschenlampe):

var widthSlider = document.querySelector('input[type=range]');
// ...
imageCapture.getPhotoCapabilities()
    .then(function(photoCapabilities) {
    widthSlider.min = photoCapabilities.imageWidth.min;
    widthSlider.max = photoCapabilities.imageWidth.max;
    widthSlider.step = photoCapabilities.imageWidth.step;
    return imageCapture.getPhotoSettings();
    })
    .then(function(photoSettings) {
    widthSlider.value = photoSettings.imageWidth;
    })
    .catch(error => console.error('Error getting camera capabilities and settings:', error));

Konfigurieren

Die Kameraeinstellungen für „Live“ können über die applyConstraints() Einschränkungen der VorschauMediaStreamTrack konfiguriert werden, z. B.:

var zoomSlider = document.querySelector('input[type=range]');

mediaStreamTrack.applyConstraints({ advanced: [{ zoom: zoomSlider.value }]})
    .catch(error => console.error('Uh, oh, applyConstraints() error:', error));

Die Kameraeinstellungen für nicht live übertragene Inhalte werden mit dem optionalen Wörterbuch PhotoSettings von takePhoto() konfiguriert, z. B.:

var widthSlider = document.querySelector('input[type=range]');
imageCapture.takePhoto({ imageWidth : widthSlider.value })
    .then(blob => {
    img.src = URL.createObjectURL(blob);
    img.onload = () => { URL.revokeObjectURL(this.src); }
    })
    .catch(error => console.error('Uh, oh, takePhoto() error:', error));

Kamerafunktionen

Wenn Sie den Code oben ausführen, werden Sie einen Unterschied in den Dimensionen zwischen den Ergebnissen für grabFrame() und takePhoto() feststellen.

Die takePhoto()-Methode bietet Zugriff auf die maximale Auflösung der Kamera.

grabFrame() nimmt einfach die nächste verfügbare VideoFrame in der MediaStreamTrack im Renderer-Prozess auf, während takePhoto() die MediaStream unterbricht, die Kamera neu konfiguriert, das Foto aufnimmt (normalerweise in einem komprimierten Format, daher Blob) und dann die MediaStreamTrack fortsetzt. Im Grunde bedeutet das, dass takePhoto() Zugriff auf die volle Auflösung der Kamera für Standbilder gewährt. Bisher war es nur möglich, ein Foto aufzunehmen, indem drawImage() auf ein canvas-Element aufgerufen wurde und ein Video als Quelle verwendet wurde (wie im Beispiel hier).

Weitere Informationen finden Sie im Abschnitt der README.md-Datei.

In dieser Demo sind die Abmessungen der <canvas> auf die Auflösung des Videostreams eingestellt, während die natürliche Größe der <canvas> der maximalen Auflösung für Standbilder der Kamera entspricht.<img> Die Darstellungsgröße der beiden wird natürlich mit CSS festgelegt.

Die gesamte Palette der verfügbaren Kameraauflösungen für Standbilder kann mithilfe der MediaSettingsRange-Werte für PhotoCapabilities.imageHeight und imageWidth abgerufen und festgelegt werden. Die Mindest- und Höchstwerte für Breite und Höhe für getUserMedia() gelten für Videos. Wie bereits erwähnt, können sie von den Kamerafunktionen für Standbilder abweichen. Mit anderen Worten: Sie können beim Speichern von getUserMedia() in ein Canvas möglicherweise nicht auf die volle Auflösung Ihres Geräts zugreifen. In der Demo zur Auflösungseinschränkung in WebRTC wird gezeigt, wie getUserMedia()-Einschränkungen für die Auflösung festgelegt werden.

Sonst noch etwas?

Demos und Codebeispiele

Support

  • Chrome 59 auf Android-Geräten und Computern
  • Chrome Canary für Android und Computer vor Version 59 mit aktivierten experimentellen Webplattform-Funktionen

Weitere Informationen