Fotos aufnehmen und Kameraeinstellungen anpassen

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

Image Capture ist eine API zur Aufnahme von Standbildern und zur Konfiguration der Kamerahardware-Einstellungen. Diese API ist in Chrome 59 für Android und Computer verfügbar. Außerdem haben wir eine Bibliothek für ImageCapture-Polyfill 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 Bilderfassung Zugriff auf die volle Auflösung aller verfügbaren Kamera- oder Webcam-Geräte erhalten. Bei früheren Techniken zum Aufnehmen von Fotos im Web wurden Video-Snapshots verwendet. Diese haben eine niedrigere Auflösung als Standbilder.

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

Bau

Die Image Capture API erhält über einen von getUserMedia() abgerufenen MediaStreamTrack 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

Für die Aufnahme gibt es zwei Möglichkeiten: Vollbild und Quick Snapshot. 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 Kameraauflösung 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, das beispielsweise auf einem <canvas> gezeichnet und dann nachbearbeitet werden kann, um Farbwerte selektiv zu ändern. ImageBitmap hat nur die Auflösung der Videoquelle. Diese ist in der Regel geringer als die Standbildfunktionen 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 eine Reihe von Möglichkeiten, die Erfassungseinstellungen zu ändern, je nachdem, ob die Änderungen in MediaStreamTrack übernommen werden oder erst nach takePhoto() angezeigt werden können. Eine Änderung der zoom-Stufe wird beispielsweise sofort auf die MediaStreamTrack übertragen, während die Rote-Augen-Reduzierung, sofern festgelegt, erst bei der Aufnahme des Fotos angewendet wird.

"Live"-Kamerafunktionen und -einstellungen werden über die Vorschau-MediaStreamTrack bearbeitet: MediaStreamTrack.getCapabilities() gibt ein MediaTrackCapabilities-Wörterbuch mit den konkreten unterstützten Funktionen und den Bereichen oder zulässigen Werten zurück, z.B. den unterstützten Zoombereich oder zulässigen Weißabgleichmodi. Entsprechend gibt MediaStreamTrack.getSettings() ein MediaTrackSettings mit den konkreten aktuellen Einstellungen zurück. Zoom, Helligkeit und Taschenlampe gehören zu dieser Kategorie. Beispiele:

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

Nicht-Live-Kamerafunktionen und -einstellungen werden über das ImageCapture-Objekt bearbeitet: ImageCapture.getPhotoCapabilities() gibt ein PhotoCapabilities-Objekt zurück, das Zugriff auf nicht live verfügbare Kamerafunktionen bietet. Entsprechend gibt ImageCapture.getPhotoSettings() ab Chrome 61 ein PhotoSettings-Objekt mit den konkreten aktuellen Einstellungen zurück. Fotoauflösung, Rote-Augen-Reduzierung und Blitzmodus (außer Taschenlampe) gehören zu diesem Abschnitt, z. B.:

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 MediaStreamTrack-Vorschau konfiguriert werden. Beispiel:

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

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

Nicht-Live-Kameraeinstellungen werden mit dem optionalen PhotoSettings-Wörterbuch von takePhoto() konfiguriert. Beispiel:

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 bei den Dimensionen zwischen den grabFrame()- und takePhoto()-Ergebnissen feststellen.

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

grabFrame() verwendet lediglich das nächste verfügbare VideoFrame im MediaStreamTrack innerhalb des Renderer-Prozesses. takePhoto() hingegen unterbricht MediaStream, konfiguriert die Kamera neu, nimmt das Foto auf (normalerweise in einem komprimierten Format, daher Blob) und setzt dann MediaStreamTrack fort. Im Wesentlichen bedeutet dies, dass takePhoto() Zugriff auf die Funktionen zur vollständigen Auflösung von Standbildern der Kamera 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 zu README.md.

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

Mit den MediaSettingsRange-Werten für PhotoCapabilities.imageHeight und imageWidth kann der gesamte Bereich der verfügbaren Kameraauflösungen für Standbilder abgerufen und festgelegt werden. Die Beschränkungen für die minimale und maximale Breite und Höhe für getUserMedia() gelten für Videos. Diese können sich (wie erläutert) von den Kamerafunktionen für Standbilder unterscheiden. Das bedeutet, dass Sie möglicherweise nicht auf die volle Auflösung Ihres Geräts zugreifen können, wenn Sie von getUserMedia() in einem Canvas speichern. Die Demo zu WebRTC-Auflösungseinschränkung zeigt, wie Sie getUserMedia()-Einschränkungen für die Auflösung festlegen.

Weitere empfohlene Schritte (optional)

  • Die Shape Detection API funktioniert gut mit Bilderfassung: grabFrame() kann wiederholt aufgerufen werden, um ImageBitmaps in ein FaceDetector- oder BarcodeDetector-Element einzuspeisen. Weitere Informationen zur API finden Sie in Paul Kinlans Blogpost.

  • Auf den Kamerablitz (Gerätelicht) kann über FillLightMode in PhotoCapabilities zugegriffen werden. Den Taschenlampenmodus (dauerhaft eingeschalteter Blitz) findest du in der MediaTrackCapabilities.

Demos und Codebeispiele

Support

  • Chrome 59 für Android und Computer
  • Chrome Canary unter Android und auf Computern vor Version 59 mit aktivierten Funktionen der experimentellen Webplattform

Weitere Informationen