A API Image Capture captura imagens estáticas e configura as configurações do hardware da câmera. Essa API está disponível no Chrome 59 para Android e computadores. Também publicamos uma biblioteca polyfill ImageCapture.
A API permite controlar recursos da câmera, como zoom, brilho, contraste, ISO e balanço de branco. O melhor de tudo é que o Image Capture permite acessar os recursos de resolução total de qualquer câmera ou webcam disponível. Técnicas anteriores para tirar fotos na Web usavam capturas de tela de vídeo, que têm resolução mais baixa do que as imagens estáticas.
Um objeto ImageCapture
é criado com um MediaStreamTrack
como origem. A
API tem dois métodos de captura takePhoto()
e grabFrame()
e maneiras de
extrair os recursos e as configurações da câmera e mudar essas
configurações.
Construção
A API Image Capture tem acesso a uma câmera por meio de uma MediaStreamTrack
obtida
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);
}
Você pode testar esse código no console do DevTools.
Capturar
A captura pode ser feita de duas maneiras: com a moldura cheia ou com o snapshot rápido. takePhoto()
retorna um Blob
, o resultado de uma única exposição fotográfica,
que pode ser feito o download, armazenado pelo navegador ou exibido em um elemento
<img>
. Esse método usa a resolução mais alta disponível da câmera fotográfica.
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 instantâneo de vídeo ao vivo,
que pode ser desenhado em um <canvas
> e processado posteriormente para
mudar seletivamente os valores de cor. O ImageBitmap
só terá 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 serão refletidas no MediaStreamTrack
ou só poderão ser
vistas após takePhoto()
. Por exemplo, uma mudança no nível de 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, o intervalo de zoom compatível ou os modos de balanço de branco permitidos.
Da mesma forma, MediaStreamTrack.getSettings()
retorna um
MediaTrackSettings
com as configurações atuais concretas. O zoom, o brilho e o modo lanterna pertencem a
essa 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 "não ao vivo" são manipulados pelo
objeto ImageCapture
: ImageCapture.getPhotoCapabilities()
retorna um
objeto PhotoCapabilities
que fornece acesso aos recursos de câmera "não ao vivo" disponíveis.
Da mesma forma, 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 lanterna) pertencem a essa 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 de câmera "Ao vivo" podem ser configuradas usando as
restrições
applyConstraints()
da visualização
MediaStreamTrack
, 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 de câmera "Não ao vivo" são configuradas com o dicionário opcional
PhotoSettings
de 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 grabFrame()
e takePhoto()
.
O método takePhoto()
dá acesso à resolução máxima da câmera.
O grabFrame()
pega a próxima VideoFrame
disponível no MediaStreamTrack
dentro do processo de renderizador, enquanto o takePhoto()
interrompe o MediaStream
,
reconfigura a câmera, tira a foto (geralmente em um formato compactado,
ou seja, o Blob
) e retoma o MediaStreamTrack
. Em essência, isso significa
que takePhoto()
dá acesso a todos os recursos de resolução de imagem
estacionária 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 da <canvas>
são definidas como a resolução do fluxo
de vídeo, enquanto o tamanho natural da <img>
é a resolução máxima de imagens
estáticas da câmera. O CSS, é claro, é usado para definir o tamanho
de exibição de ambos.
A gama completa de resoluções de câmera disponíveis para imagens estáticas pode ser acessada e definida
usando os valores MediaSettingsRange
para PhotoCapabilities.imageHeight
e
imageWidth
. As restrições de largura e altura mínimas e máximas de
getUserMedia()
são para vídeos, 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 os recursos de resolução total do seu dispositivo ao salvar de
getUserMedia()
para 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 imagem:
grabFrame()
pode ser chamada repetidamente para alimentarImageBitmap
s para 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 por
FillLightMode
emPhotoCapabilities
, mas o modo de tocha (flash constantemente ativado) pode ser encontrado noMediaTrackCapabilities
.
Demonstrações e exemplos de código
- Demo do Chrome Samples
- simpl.info/ic (link em inglês)
- Exemplos do WebRTC
Suporte
- Chrome 59 no Android e no computador.
- Chrome Canary no Android e no computador anteriores à versão 59 com recursos da Plataforma Web Experimental ativados.