O Image Capture é uma API para capturar imagens estáticas e definir as configurações de hardware da câmera. Essa API está disponível no Chrome 59 para Android e computadores. Além disso, publicamos uma biblioteca de polyfill de ImageCapture (link em inglês).
Essa API permite controlar os recursos da câmera, como zoom, brilho, contraste, ISO e balanço de branco. O melhor de tudo é que a captura de imagens permite acessar os recursos de resolução máxima de qualquer câmera ou webcam de dispositivo disponível. As técnicas anteriores de captura de fotos na Web usavam snapshots de vídeo, que têm resolução menor do que a disponível para imagens estáticas.
Um objeto ImageCapture
é construído com um MediaStreamTrack
como origem. A
API tem dois métodos de captura takePhoto()
e grabFrame()
, além de maneiras de
recuperar os recursos e as configurações da câmera e mudar essas
configurações.
Obras
A API Image Capture tem acesso a uma câmera por meio de um MediaStreamTrack
recebido
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);
}
Teste esse código no console do DevTools.
Capturar
A captura pode ser feita de duas maneiras: frame completo e snapshot rápido. takePhoto()
retorna um Blob
, o resultado de uma única exposição fotográfica,
que pode ser transferido por download, armazenado pelo navegador ou exibido em um elemento
<img>
. Esse método usa a resolução de câmera fotográfica mais alta disponível.
Exemplo:
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()
retorna um objeto ImageBitmap
, um snapshot do vídeo ao vivo,
que pode, por exemplo, ser desenhado em um <canvas
> e depois pós-processado para
mudar seletivamente os valores de cor. A ImageBitmap
terá apenas a
resolução da fonte de vídeo, que geralmente é menor do que os recursos de
imagem estática da câmera. Exemplo:
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));
Recursos e configurações
Há várias maneiras de manipular as configurações de captura, dependendo
se as mudanças vão ser refletidas no MediaStreamTrack
ou só podem ser
encontradas depois de takePhoto()
. Por exemplo, uma mudança no nível zoom
é imediatamente
propagada para o MediaStreamTrack
, enquanto a redução de olhos vermelhos, quando definida, é
aplicada apenas quando a foto está sendo tirada.
Os recursos e as configurações da câmera "ao vivo" são manipulados pela visualização
MediaStreamTrack
: MediaStreamTrack.getCapabilities()
retorna um dicionário
MediaTrackCapabilities
com os recursos compatíveis concretos e os intervalos ou valores
permitidos, por exemplo, intervalo de zoom ou modos de balanço de branco permitidos.
De maneira correspondente, MediaStreamTrack.getSettings()
retorna um
MediaTrackSettings
com as configurações atuais concretas. O zoom, o brilho e o modo da lanterna pertencem a
esta categoria. Por exemplo:
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;
}
Os recursos e as configurações da câmera "inativa" são manipulados pelo objeto
ImageCapture
: ImageCapture.getPhotoCapabilities()
retorna um objeto
PhotoCapabilities
que fornece acesso a recursos de câmera "inativos".
De forma correspondente, a partir do Chrome 61, ImageCapture.getPhotoSettings()
retorna um objeto
PhotoSettings
com as configurações atuais concretas. A resolução da foto, a redução de olhos vermelhos
e o modo de flash (exceto a lanterna) pertencem a esta seção, por exemplo:
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
As configurações da câmera "Ao vivo" podem ser definidas usando as
restrições
applyConstraints()
de MediaStreamTrack
de visualização, por exemplo:
var zoomSlider = document.querySelector('input[type=range]');
mediaStreamTrack.applyConstraints({ advanced: [{ zoom: zoomSlider.value }]})
.catch(error => console.error('Uh, oh, applyConstraints() error:', error));
As configurações da câmera "Inativa" são definidas com o dicionário opcional
PhotoSettings
do takePhoto()
, por exemplo:
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));
Recursos da câmera
Se você executar o código acima, vai notar uma diferença nas dimensões entre os resultados de
grabFrame()
e takePhoto()
.
O método takePhoto()
dá acesso à resolução máxima da câmera.
grabFrame()
usa apenas o próximo VideoFrame
disponível no MediaStreamTrack
dentro do processo do renderizador, enquanto takePhoto()
interrompe o MediaStream
,
reconfigura a câmera, tira a foto (geralmente em formato compactado,
portanto, Blob
) e depois retoma o MediaStreamTrack
. Basicamente, isso significa
que takePhoto()
concede acesso aos recursos completos de resolução de imagem estática
da câmera. Antes, só era possível "tirar uma foto"
chamando drawImage()
em um elemento canvas
, usando um vídeo como origem (conforme o
exemplo aqui).
Mais informações podem ser encontradas na seção README.md.
Nesta demonstração, as dimensões de <canvas>
são definidas como a resolução do stream de vídeo, enquanto o tamanho natural do <img>
é a resolução máxima de imagem estática da câmera. O CSS, obviamente, é usado para definir o tamanho de exibição de ambos.
É possível acessar e definir a gama completa de resoluções de câmera disponíveis para imagens estáticas
usando os valores MediaSettingsRange
para PhotoCapabilities.imageHeight
e
imageWidth
. As restrições de largura e altura mínimas e máximas para
getUserMedia()
são para vídeo, que, como discutido, podem ser diferentes dos
recursos da câmera para imagens estáticas. Em outras palavras, talvez não seja possível
acessar todos os recursos de resolução do seu dispositivo ao salvar de
getUserMedia()
em uma tela. A demonstração de restrição de resolução
do WebRTC mostra como definir restrições getUserMedia()
para resolução.
Mais alguma coisa?
A API Shape Detection funciona bem com a captura de imagens:
grabFrame()
pode ser chamado repetidamente para alimentarImageBitmap
s em umFaceDetector
ouBarcodeDetector
. Saiba mais sobre a API na postagem do blog de Paul Kinlan.O Flash da câmera (luz do dispositivo) pode ser acessado via
FillLightMode
emPhotoCapabilities
, mas o modo lanterna (pisca constantemente ativado) pode ser encontrado emMediaTrackCapabilities
.
Demonstrações e exemplos de código
Suporte
- Chrome 59 no Android e no computador.
- Chrome Canary no Android e em computadores anteriores à versão 59 com os recursos da Plataforma Web experimental ativados.