Fotos aufnehmen und Kameraeinstellungen anpassen

Miguel Casas-Sanchez
Beaufort
François Beaufort

Image Capture ist eine API zum Aufnehmen von Standbildern und zum Konfigurieren der Einstellungen für die Kamerahardware. Diese API ist in Chrome 59 für Android und auf Computern verfügbar. Außerdem haben wir eine ImageCapture-Polyfill-Bibliothek veröffentlicht.

Mit der API lassen sich Kamerafunktionen wie Zoom, Helligkeit, Kontrast, ISO und Weißabgleich steuern. Und das Beste ist: Mit der Bilderfassung haben Sie Zugriff auf die volle Auflösung aller verfügbaren Gerätekameras. Bei früheren Verfahren zum Aufnehmen von Fotos im Web wurden Videoschnappschüsse verwendet, die eine geringere Auflösung als für Standbilder verfügbar haben.

Ein ImageCapture-Objekt wird mit einer MediaStreamTrack als Quelle konstruiert. Die API bietet dann die beiden Aufnahmemethoden takePhoto() und grabFrame() sowie Möglichkeiten, die Funktionen und Einstellungen der Kamera abzurufen und zu ändern.

Baustelle

Die Image Capture API erhält über ein MediaStreamTrack von getUserMedia() Zugriff auf eine Kamera:

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);
}

Du kannst diesen Code in der Entwicklertools-Konsole ausprobieren.

Aufnehmen

Es gibt zwei Möglichkeiten, Aufnahmen im Vollbild oder in einer Momentaufnahme zu machen. takePhoto() gibt eine Blob zurück, das Ergebnis einer einzelnen fotografischen Belichtung, die 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. Dies ist ein Snapshot eines Live-Videos, der beispielsweise auf einem <canvas>-Element gezeichnet und dann nachbearbeitet werden kann, um selektiv Farbwerte zu ändern. ImageBitmap enthält nur die Auflösung der Videoquelle – diese ist in der Regel niedriger als die Standbildfunktion der Kamera. 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 Erfassungseinstellungen zu bearbeiten. Das hängt davon ab, ob die Änderungen in MediaStreamTrack übernommen werden oder erst nach takePhoto() sichtbar sind. Beispielsweise wird eine Änderung des zoom-Levels sofort auf MediaStreamTrack übertragen, während die Rote-Augen-Reduzierung, sofern sie festgelegt ist, nur während der Aufnahme des Fotos angewendet wird.

Die Kamerafunktionen und -einstellungen von „Live“ werden über die Vorschau-MediaStreamTrack geändert: MediaStreamTrack.getCapabilities() gibt ein MediaTrackCapabilities-Wörterbuch mit den konkreten unterstützten Funktionen und den Bereichen oder zulässigen Werten zurück, z.B. dem unterstützten Zoombereich oder den zulässigen Weißabgleichmodi. MediaStreamTrack.getSettings() gibt entsprechend ein MediaTrackSettings mit den konkreten aktuellen Einstellungen zurück. Zu dieser Kategorie gehören der Zoom, die Helligkeit und der Taschenlampenmodus. Beispiel:

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 live sind, werden über das ImageCapture-Objekt geändert: ImageCapture.getPhotoCapabilities() gibt ein PhotoCapabilities-Objekt zurück, das Zugriff auf verfügbare Kamerafunktionen für „Nicht-Live“ bietet. Entsprechend gibt ImageCapture.getPhotoSettings() ab Chrome 61 ein PhotoSettings-Objekt mit den konkreten aktuellen Einstellungen zurück. Zu diesem Abschnitt gehören die Fotoauflösung, die Rote-Augen-Reduzierung und der Blitzmodus (außer Taschenlampe). Beispiele:

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

Kameraeinstellungen für „Live“ können über die Einschränkungen für applyConstraints() der Vorschau-MediaStreamTrack 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));

„Non-Live“-Kameraeinstellungen werden mit dem optionalen PhotoSettings-Wörterbuch 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 obigen Code ausführen, werden Sie einen Unterschied in den Dimensionen zwischen den Ergebnissen grabFrame() und takePhoto() feststellen.

Die Methode takePhoto() gewährt Zugriff auf die maximale Auflösung der Kamera.

grabFrame() verwendet nur das nächste verfügbare VideoFrame im MediaStreamTrack innerhalb des Rendererprozesses. takePhoto() unterbricht das MediaStream, konfiguriert die Kamera neu, nimmt das Foto auf (normalerweise in einem komprimierten Format, daher das Blob) und setzt MediaStreamTrack fort. Im Wesentlichen bedeutet dies, dass takePhoto() Zugriff auf alle Funktionen der Kamera zur Auflösung von Standbildern gewährt. Bisher war es nur möglich, ein Foto aufzunehmen, indem drawImage() für ein canvas-Element aufgerufen und ein Video als Quelle verwendet wurde (siehe Beispiel).

Weitere Informationen finden Sie im Abschnitt "Readme.md".

In dieser Demo werden die Abmessungen für <canvas> auf die Auflösung des Videostreams festgelegt, während die natürliche Größe von <img> die maximale Standbildauflösung der Kamera ist. Natürlich wird CSS verwendet, um die Anzeigegröße beider Elemente festzulegen.

Der gesamte Bereich der verfügbaren Kameraauflösungen für Standbilder kann mithilfe der MediaSettingsRange-Werte für PhotoCapabilities.imageHeight und imageWidth abgerufen und festgelegt werden. Die minimalen und maximalen Breiten- und Höhenbeschränkungen für getUserMedia() gelten für Videos. Sie können sich, wie erläutert, von den Kamerafunktionen für Standbilder unterscheiden. Mit anderen Worten, Sie können möglicherweise nicht auf die volle Auflösung Ihres Geräts zugreifen, wenn Sie von getUserMedia() in einem Canvas speichern. Die WebRTC-Demo zu Auflösungseinschränkungen zeigt, wie getUserMedia()-Einschränkungen für die Auflösung festgelegt werden.

Sonst noch etwas?

  • Die Shape Detection API funktioniert gut mit der Bilderfassung: grabFrame() kann wiederholt aufgerufen werden, um ImageBitmaps an FaceDetector oder BarcodeDetector zu übergeben. Weitere Informationen zur API finden Sie im Blogpost von Paul Kinlan.

  • Auf den Kamerablitz (Gerätelicht) kann über FillLightMode in PhotoCapabilities zugegriffen werden. Den Taschenlampenmodus, bei dem der Blitz dauerhaft aktiviert ist, finden Sie in der MediaTrackCapabilities.

Demos und Codebeispiele

Support

  • Chrome 59 für Android und Computer
  • Chrome Canary auf Android- und Desktopgeräten vor Version 59 mit aktivierten experimentellen Webplattformfunktionen

Weitere Informationen