Prendre des photos et contrôler les paramètres de l'appareil photo

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

Image Capture est une API permettant de prendre des images fixes et de configurer le matériel de l'appareil photo. paramètres. Cette API est disponible dans Chrome 59 sur Android et sur ordinateur. Nous avons également publié une bibliothèque polyfill ImageCapture.

L'API permet de contrôler les fonctionnalités de l'appareil photo telles que le zoom, la luminosité, le contraste, l'ISO et la balance des blancs. Cerise sur le gâteau, la capture d'image vous permet d'accéder les capacités de haute résolution de n'importe quelle caméra ou webcam disponible de l'appareil. Auparavant, les techniques permettant de prendre des photos sur le Web utilisaient auparavant les instantanés vidéo, dont la résolution est inférieure à celle disponible pour les images fixes.

Un objet ImageCapture est construit avec un MediaStreamTrack comme source. La L'API dispose alors de deux méthodes de capture : takePhoto() et grabFrame(), et vous permet de récupérer les fonctionnalités et les réglages de l'appareil photo, et les modifier paramètres.

Construction

L'API Image Capture accède à un appareil photo via un MediaStreamTrack de getUserMedia():

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

Vous pouvez essayer ce code à partir de la console DevTools.

Filmez

Vous pouvez prendre une photo de deux façons: en mode plein écran ou en mode Instantané rapide. takePhoto() renvoie une Blob, le résultat d'une seule exposition photographique, téléchargeables, stockées par le navigateur ou affichées dans un <img> . Cette méthode utilise la résolution d'appareil photo la plus élevée disponible. Exemple :

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() renvoie un objet ImageBitmap, un instantané d'une vidéo en direct, qui pourrait (par exemple) être dessinée sur une <canvas> puis post-traités modifier de manière sélective les valeurs de couleur. Notez que ImageBitmap n'aura que la résolution de la source vidéo (généralement inférieure à celle de la caméra). des images fixes. Exemple :

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

Fonctionnalités et paramètres

Il existe plusieurs façons de manipuler les paramètres de capture, en fonction si les modifications seront répercutées dans MediaStreamTrack ou uniquement vue après le takePhoto(). Par exemple, un changement de niveau zoom est immédiatement propagée vers MediaStreamTrack, tandis que la réduction de l'yeux rouges, lorsqu'elle est définie, est appliqué uniquement lors de la prise de la photo.

"En direct" les fonctionnalités et les paramètres de l'appareil photo sont manipulés via l'aperçu ; MediaStreamTrack: MediaStreamTrack.getCapabilities() renvoie un MediaTrackCapabilities avec les capacités concrètes acceptées et les plages ou les valeurs autorisées telles que plage de zoom compatible ou modes de balance des blancs autorisés. Par conséquent, MediaStreamTrack.getSettings() renvoie une MediaTrackSettings avec les paramètres actuels concrets. Le zoom, la luminosité et le mode de la lampe de poche appartiennent cette catégorie, par exemple:

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

"Non en ligne" les fonctionnalités et les paramètres de la caméra sont manipulés via la Objet ImageCapture: ImageCapture.getPhotoCapabilities() renvoie une PhotoCapabilities qui donne accès à l'état "Non-Live" de l'appareil photo disponibles. En conséquence, à partir de Chrome 61, ImageCapture.getPhotoSettings() renvoie un PhotoSettings avec les paramètres actuels concrets. La résolution de la photo, les yeux rouges et le mode flash (à l'exception de la lampe de poche) appartiennent à cette section, par exemple:

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

Configuration

"En direct" les paramètres de la caméra peuvent être configurés dans la version preview applyConstraints() de MediaStreamTrack contraintes , par exemple:

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

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

"Non en ligne" les paramètres de la caméra sont configurés avec le paramètre facultatif du takePhoto() PhotoSettings par exemple:

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

Fonctionnalités de l'appareil photo

Si vous exécutez le code ci-dessus, vous remarquerez une différence de dimensions entre les Résultats pour grabFrame() et takePhoto().

La méthode takePhoto() permet d'accéder à la résolution maximale de l'appareil photo.

grabFrame() vient de remporter le prochain VideoFrame disponible dans MediaStreamTrack dans le processus du moteur de rendu, tandis que takePhoto() interrompt MediaStream, reconfigure l'appareil photo, prend la photo (généralement dans un format compressé, d'où le Blob), puis réactive MediaStreamTrack. Concrètement, cela signifie que takePhoto() donne accès à la résolution maximale des images fixes de l'appareil photo. Auparavant, il était uniquement possible de "prendre une photo" par appeler drawImage() sur un élément canvas, en utilisant une vidéo comme source (conformément aux cliquez ici pour voir un exemple).

Pour en savoir plus, consultez la section README.md.

Dans cette démonstration, les dimensions <canvas> sont définies sur la résolution de la vidéo. flux, tandis que la taille naturelle de <img> correspond à l'image fixe maximale la résolution de l'appareil photo. Le langage CSS, bien sûr, permet de définir l'affichage la taille des deux.

Vous pouvez obtenir et régler l'ensemble des résolutions d'appareil photo disponibles pour les images fixes. en utilisant les valeurs MediaSettingsRange pour PhotoCapabilities.imageHeight et imageWidth Notez que les contraintes minimales et maximales de largeur et de hauteur getUserMedia() sont destinés aux vidéos, qui (comme nous l'avons vu) peuvent être différents des des fonctionnalités de l'appareil photo pour les images fixes. En d'autres termes, vous ne pourrez peut-être pas accéder à la résolution maximale de votre appareil lorsque vous enregistrez getUserMedia() sur un canevas. Démonstration des contraintes de résolution WebRTC montre comment définir des contraintes getUserMedia() pour la résolution.

Autre chose ?

  • L'API Shape Detection fonctionne bien avec Image Capture: grabFrame() peut être appelé plusieurs fois pour alimenter ImageBitmap en FaceDetector ou BarcodeDetector. En savoir plus sur les dans l'article de blog Paul Kinlan.

  • Le flash de l'appareil photo (voyant de l'appareil) est accessible via FillLightMode po PhotoCapabilities , mais vous pouvez trouver le mode Torche (clignotement permanent) dans la MediaTrackCapabilities

Démonstrations et exemples de code

Assistance

  • Chrome 59 sur Android et ordinateur.
  • Chrome Canary sur Android et ordinateur de bureau antérieur à la version 59 avec Fonctionnalités de la plate-forme Web expérimentale activées.

En savoir plus