Cómo tomar fotos y controlar la configuración de la cámara

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

Image Capture es una API para capturar imágenes fijas y configurar el hardware de la cámara configuración. Esta API está disponible en Chrome 59 en Android y computadoras de escritorio. También hemos publicó una biblioteca de polyfills de ImageCapture.

La API permite controlar las funciones de la cámara, como el zoom, el brillo, contraste, ISO y balance de blancos. Lo mejor de todo es que la Captura de imágenes permite acceder las capacidades de resolución completa de cualquier cámara o cámara web disponible del dispositivo. Las técnicas anteriores para tomar fotos en la Web usan instantáneas de video, que tienen una resolución inferior a la disponible para las imágenes fijas.

Se construye un objeto ImageCapture con un MediaStreamTrack como fuente. El La API tiene dos métodos de captura, takePhoto() y grabFrame(), y formas de recuperar las capacidades y la configuración de la cámara, y cambiarlas configuración.

Construcción

La API de Image Capture obtiene acceso a una cámara a través de un MediaStreamTrack obtenido 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);
}

Puedes probar este código desde la consola de Herramientas para desarrolladores.

Captura

La captura se puede realizar de dos maneras: fotograma completo e instantánea rápida. takePhoto() devuelve un Blob, el resultado de una sola exposición fotográfica. que puede descargarse, almacenarse en el navegador o mostrarse en un archivo <img> . Este método usa la resolución de cámara fotográfica más alta disponible. Por ejemplo:

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() muestra un objeto ImageBitmap, una instantánea del video en vivo. que podría, por ejemplo, dibujarse en una <canvas> y, luego, se procesa de forma posterior cambiar selectivamente los valores de color. Ten en cuenta que ImageBitmap solo tendrá el elemento resolución de la fuente de video, que suele ser inferior a la de la cámara imágenes fijas. Por ejemplo:

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

Funciones y configuración

Hay varias formas de manipular la configuración de captura, según si los cambios se reflejarán en el MediaStreamTrack o solo visto después del takePhoto(). Por ejemplo, un cambio en el nivel de zoom se produce inmediatamente se propaga a MediaStreamTrack, mientras que la reducción de ojos rojos, cuando se establece, solo se aplica cuando se toma la foto.

"Publicada" se manipulan las capacidades y la configuración de la cámara en la vista previa. MediaStreamTrack: MediaStreamTrack.getCapabilities() muestra un MediaTrackCapabilities diccionario con las capacidades concretas admitidas y los rangos o permitidos valores, p.ej., el rango de zoom admitido o los modos de balance de blancos permitidos. En consecuencia, MediaStreamTrack.getSettings() muestra un MediaTrackSettings con la configuración actual concreta. El zoom, el brillo y el modo linterna pertenecen a esta categoría, por ejemplo:

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

"No publicadas" las capacidades y la configuración de la cámara se manipulan con el Objeto ImageCapture: ImageCapture.getPhotoCapabilities() muestra un PhotoCapabilities objeto que proporciona acceso a contenido "No publicado" y capacidades de cámara disponibles. En consecuencia, a partir de Chrome 61, ImageCapture.getPhotoSettings() devuelve un PhotoSettings con la configuración actual concreta. La resolución de la foto, ojos rojos la reducción y el modo de flash (excepto linterna) pertenecen a esta sección, por ejemplo:

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

Configurando

"Publicada" ajustes de la cámara en la vista previa applyConstraints() de MediaStreamTrack restricciones , por ejemplo:

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

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

"No publicadas" Los parámetros de configuración de la cámara se establecen con el permiso opcional de takePhoto() PhotoSettings diccionario, por ejemplo:

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

Capacidades de la cámara

Si ejecutas el código anterior, notarás una diferencia en las dimensiones entre los Resultados de grabFrame() y takePhoto().

El método takePhoto() otorga acceso a la resolución máxima de la cámara.

grabFrame() solo se queda con el próximo VideoFrame disponible en MediaStreamTrack dentro del proceso del renderizador, mientras que takePhoto() interrumpe MediaStream, reconfigura la cámara, toma la foto (generalmente en un formato comprimido, por lo tanto, Blob) y, luego, reanuda MediaStreamTrack. En esencia, esto significa que takePhoto() otorgue acceso a la resolución completa de la imagen fija capacidades de la cámara. Anteriormente, solo se podía "tomar una foto" de la siguiente manera: llamando a drawImage() en un elemento canvas con un video como fuente (según el aquí).

Para obtener más información, consulta la sección de README.md.

En esta demostración, las dimensiones de <canvas> se establecen según la resolución del video. de transmisión, mientras que el tamaño natural de <img> es la imagen estática máxima resolución de la cámara. CSS, por supuesto, se usa el tamaño de ambos.

Se puede obtener y configurar la gama completa de resoluciones de cámara disponibles para las imágenes fijas. usando los valores de MediaSettingsRange para PhotoCapabilities.imageHeight y imageWidth Ten en cuenta que las restricciones de ancho y altura mínimos y máximos para getUserMedia() son para video, que, como se explicó, pueden ser diferentes de la capacidades de la cámara para las imágenes fijas. En otras palabras, es posible que no puedas acceder a las capacidades de resolución completa de tu dispositivo cuando guardes getUserMedia() a un lienzo. La demostración de la restricción de resolución de WebRTC se muestra cómo establecer restricciones de getUserMedia() para la resolución.

¿Algo más?

  • La API de Shape Detection Funciona bien con la captura de imágenes: se puede llamar a grabFrame() varias veces para alimentar ImageBitmap a FaceDetector o BarcodeDetector. Obtén más información sobre la API de la entrada de blog de Paul Kinlan.

  • Se puede acceder al Flash de la cámara (luz del dispositivo) con FillLightMode in PhotoCapabilities , pero el modo linterna (parpadea constantemente encendido) se encuentra en la MediaTrackCapabilities.

Demostraciones y muestras de código

Asistencia

  • Chrome 59 en Android y computadoras de escritorio
  • Chrome Canary en Android y computadoras de escritorio anteriores a la versión 59 con Se habilitaron las funciones de la plataforma web experimental.

Más información