Pesquisa de site

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