Image Capture es una API que captura imágenes estáticas y configura el hardware de la cámara. Esta API está disponible en Chrome 59 en Android y computadoras de escritorio. También publicamos una biblioteca de polyfills ImageCapture.
La API permite controlar las funciones de la cámara, como el zoom, el brillo, el contraste, la escala ISO y el balance de blancos. Lo mejor de todo es que la captura de imágenes te permite acceder a las capacidades de resolución completa de cualquier cámara o cámara web de un dispositivo disponible. En las técnicas anteriores para tomar fotos en la Web, se utilizaban instantáneas de video, que tienen una resolución menor que la disponible para imágenes estáticas.
Un objeto ImageCapture
se construye con un MediaStreamTrack
como origen. Luego, la API tiene dos métodos de captura, takePhoto()
y grabFrame()
, y formas de recuperar las capacidades y los parámetros de configuración de la cámara, y de cambiar esos parámetros de configuración.
Construcción
La API de captura de imágenes 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 hacer de dos maneras: en fotograma completo e instantánea rápida. takePhoto()
muestra un Blob
, el resultado de una sola exposición fotográfica, que se puede descargar, almacenar en el navegador o mostrar en un elemento <img>
. Este método utiliza 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 de un video en vivo que, por ejemplo, podría dibujarse en un <canvas
> y, luego, procesarse posteriormente para cambiar de forma selectiva los valores de color. Ten en cuenta que ImageBitmap
solo tendrá la resolución de la fuente de video, que suele ser más baja que las capacidades de imagen fija de la cámara. 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 si solo se podrán ver después de takePhoto()
. Por ejemplo, un cambio en el nivel de zoom
se propaga de inmediato al MediaStreamTrack
, mientras que la reducción de ojos rojos, cuando se configura, solo se aplica cuando se toma la foto.
Las capacidades y la configuración de la cámara "en vivo" se manipulan a través de la vista previa MediaStreamTrack
: MediaStreamTrack.getCapabilities()
muestra un diccionario MediaTrackCapabilities
con las capacidades concretas admitidas y los rangos o valores permitidos, p.ej., el rango de zoom o los modos de balance de blancos admitidos.
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;
}
Las capacidades y la configuración de la cámara "no publicadas" se manipulan mediante el objeto ImageCapture
: ImageCapture.getPhotoCapabilities()
muestra un objeto PhotoCapabilities
que proporciona acceso a las funciones de la cámara disponibles para el estado "No publicado".
En consecuencia, a partir de Chrome 61, ImageCapture.getPhotoSettings()
muestra un objeto PhotoSettings
con la configuración actual concreta. La resolución de la foto, la reducción de ojos rojos y el modo de flash (excepto la 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));
Configuración
La configuración de la cámara "en vivo" se puede establecer mediante las restricciones de applyConstraints()
de la vista previa de MediaStreamTrack
, por ejemplo:
var zoomSlider = document.querySelector('input[type=range]');
mediaStreamTrack.applyConstraints({ advanced: [{ zoom: zoomSlider.value }]})
.catch(error => console.error('Uh, oh, applyConstraints() error:', error));
La configuración de la cámara "No publicada" se establece con el diccionario opcional PhotoSettings
de takePhoto()
, 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 de 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 toma el siguiente VideoFrame
disponible en el MediaStreamTrack
dentro del proceso del renderizador, mientras que takePhoto()
interrumpe el MediaStream
, reconfigura la cámara, toma la foto (por lo general, en un formato comprimido, por lo tanto, Blob
) y, luego, reanuda la MediaStreamTrack
. En esencia, esto significa que takePhoto()
otorga acceso a las capacidades completas de resolución de imagen fija de la cámara. Anteriormente, solo era posible "tomar una foto" llamando a drawImage()
en un elemento canvas
con un video como fuente (como se ve aquí).
Para obtener más información, consulta la sección README.md.
En esta demostración, las dimensiones <canvas>
se establecen en la resolución de la transmisión de video, mientras que el tamaño natural de <img>
es la resolución máxima de imágenes estáticas de la cámara. CSS, por supuesto, se usa para establecer el tamaño de visualización de ambos.
Se puede obtener y configurar el rango completo de resoluciones de cámara disponibles para imágenes estáticas mediante los valores de MediaSettingsRange
para PhotoCapabilities.imageHeight
y imageWidth
. Ten en cuenta que las restricciones mínimas y máximas de ancho y altura de getUserMedia()
se aplican a los videos y, como se explicó, pueden diferir de las capacidades de la cámara para imágenes estáticas. En otras palabras, es posible que no puedas acceder a las capacidades de resolución completa del dispositivo cuando guardes contenido de getUserMedia()
en un lienzo. En 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()
de forma repetida para enviarImageBitmap
a unFaceDetector
oBarcodeDetector
. Obtén más información sobre la API en esta entrada de blog de Paul Kinlan.Se puede acceder al Flash de la cámara (luz del dispositivo) a través de
FillLightMode
enPhotoCapabilities
, pero puedes encontrar el modo linterna (parpadeo constante) enMediaTrackCapabilities
.
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 las funciones de la plataforma web experimental habilitadas.