javascript - Varför ritar ctx.drawImage bara en del av videoelementet på canvas?
Jag försöker rita en filmruta på canvas-elementet med ctx.DrawImage och jag får vad jag tror är mycket konstiga skalnings-/beskärningsbeteenden.
Först, här är min kod:
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;
});
Vad detta gör är i princip att ta bilden från videon och trycka ihop den så att den är ungefär 1/3 av den ursprungliga bredden och ungefär 70% av höjden. Detta är frustrerande.
Att ta bort 125 och bara använda ctx.drawImage(video, 0, 0) fyller duken med bilden, men det är bara ungefär det övre vänstra hörnet (25%) av bilden. Detta är också frustrerande.
Hur kan jag få duken att rita en bild i exakt samma storlek som videoelementet spelar?
Detta är kopplat till det faktum att videoelementet i sig faktiskt är 125px x 125px, men på grund av bildförhållandet finns det bokstavsfält (vit yta) runt videoelementet. Finns det ett sätt att tvinga videoelementet att fylla sig själv med den inkommande videoströmmen?
Svar #1
Jag stod också inför samma problem när jag försökte...
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);
det löstes när jag ändrade till :
ctx.drawImage(video, 0, 0, dw, dh);
Jag tror att problemet i ditt fall är att 125 är höjden och bredden på videoelementet, men det du bör ange är canvasens höjd och bredd, till exempel genom att ställa in canvasens bredd och höjd:
canvas.width = 125;
canvas.height = 125;
ctx.drawImage(video, 0, 0, 125, 125);
Svar #2
Jag använde en webbkamera (med funktionen navigator.getUserMedia). Webbkamerans upplösning var betydligt högre och så, även när storlekarna på videoelementet och canvasen var desamma, var bilden som fångades mycket större än vad som fick plats.
Lösningen var att lägga till en constrain-egenskap för att göra mediastreamen också 125px x 125px
