javascript - Por que ctx.drawImage está desenhando apenas parte do elemento de vídeo no canvas?
Estou tentando desenhar um quadro de filme no elemento canvas usando ctx.DrawImage e estou obtendo o que acho que são comportamentos de escala/corte muito estranhos.
Primeiro, aqui está o meu código:
HTML
<body>
<video autoplay width="125" height="125"></video>
<img src="">
<canvas></canvas>
</body>
Javascript:
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var localMediaStream = null;
function snapshot() {
if (localMediaStream) {
ctx.drawImage(video, 0, 0, 125, 125);
document.querySelector('img').src = canvas.toDataURL('image/webp');
}
}
video.addEventListener('click', snapshot, false);
navigator.getUserMedia(
{
video: true
}, function(stream) {
video.src = window.URL.createObjectURL(stream);
localMediaStream = stream;
});
O que isso faz é basicamente pegar a imagem estática do vídeo e comprimi-la para que tenha cerca de 1/3 da largura original e cerca de 70% da altura. Isso é frustrante.
Omitindo o 125 e apenas usando ctx.drawImage(video, 0, 0) preenche a tela com a imagem estática, no entanto, é apenas cerca do canto superior esquerdo (25%) da imagem. Isso também é frustrante.
Como posso fazer o canvas desenhar a imagem exatamente do mesmo tamanho que o elemento de vídeo está reproduzindo?
Isso é combinado com o fato de que o próprio elemento de vídeo é de fato 125px x 125px, mas por causa da proporção, há letter boxing (espaço em branco) ao redor do elemento de vídeo. Existe uma maneira de forçar o elemento de vídeo a se preencher com o fluxo de vídeo recebido?
Resposta #1
Eu também estava enfrentando o mesmo problema quando tentei...
var sw = video.offsetWidth, // source width
sh = video.offsetHeight, // source height
dw = canvas.width, // destination width
dh = canvas.height; // destination height
ctx.drawImage(video, 0, 0, sw, sh, 0, 0, dw, dh);
foi resolvido quando eu mudei para :
ctx.drawImage(video, 0, 0, dw, dh);
Acredito que no seu caso o problema é que 125 é a altura e largura do elemento de vídeo, mas o que você deveria fornecer é a altura e a largura do canvas, por exemplo, definindo a largura e a altura do canvas:
canvas.width = 125;
canvas.height = 125;
ctx.drawImage(video, 0, 0, 125, 125);
Resposta #2
Eu estava usando uma webcam (com a função navigator.getUserMedia). A resolução da webcam era significativamente maior e, portanto, mesmo quando os tamanhos do elemento de vídeo e do canvas eram os mesmos, a imagem capturada era muito maior do que caberia.
A solução foi adicionar uma propriedade constrain para fazer com que o fluxo de mídia também tivesse 125px x 125px
