Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5: crazy canvas drawImage sizing

I have the next html template:

<div className="page">
    <video id="video" autoPlay/>
    <canvas id="canvas"/>
    <div class="btn-wrapper">
        <button onClick={this._takePhoto}>Snap Photo</button>
    </div>
</div>

Here is screenshot of my app. At the top you can see <video> and at the bottom <canvas/> (focus in devtools).

enter image description here

Problem: to draw <video/> picture to <canvas/> I should use this strange coefficients:

    const canvas = document.getElementById('canvas'),
          context = canvas.getContext("2d"),
          video = document.getElementById('video');
    //QUESTION: why?!
    const widthCoef = 2.1,
          heigthCoef = 3;
    context.drawImage(video, 
                      0, 
                      0, 
                      video.clientWidth * widthCoef, 
                      video.clientHeight * heightCoef, 
                      0, 
                      0, 
                      canvas.clientWidth, 
                      canvas.clientHeight);

Question: why I should use coefficients if <video/> & <canvas/> have the same width/height?


If I do the same but without coefficients, like

context.drawImage(video, 0, 0, video.clientWidth, video.clientHeight, 0, 0, canvas.clientWidth, canvas.clientHeight); //OR
context.drawImage(video, 0, 0, video.clientWidth, video.clientHeight, 0, 0, video.clientWidth, video.clientHeight); //OR
context.drawImage(video, 0, 0, canvas.clientWidth, canvas.clientHeight, 0, 0, canvas.clientWidth, canvas.clientHeight);

I get a zoomed picture:

enter image description here

UPDATE

My new resizing version:

_resizeCanvas() {
    const canvas = document.getElementById('canvas'),
        video = document.getElementById('video');
    const width = +window.getComputedStyle(video, null).getPropertyValue('width').replace('px', ''),
          height = +window.getComputedStyle(video, null).getPropertyValue('height').replace('px', '');
    video.width = width;
    video.height = height;
    canvas.width = width;
    canvas.height = height;
},

UPDATE 2 - add fiddle example

Here is my fiddle example

like image 429
VB_ Avatar asked Mar 10 '26 00:03

VB_


1 Answers

Those magic coefficients correspond to the ratio between the video object size and the size of canvas.

Suppose, your video size is (400 x 300) and you want to show it on the canvas with size (200 x 150). It can be done just by:

context.drawImage(video,0,0,200,150);

It will resize full video to fit the canvas.

However, you are using clipping version of drawImage(). The first four coordinate arguments describe clipping parameters. For example in the following case it takes quarter of full video:

context.drawImage(video,0,0,200,150,0,0,200,150);

Edit according to updated question

The image is clipped, since properties canvas.clientWidth and canvas.clientHeight are larger than canvas.width and canvas.height. That happens because of CSS display: flex;. To show full image use:

context.drawImage(video, 0, 0, canvas.width, canvas.height);
like image 122
Orest Hera Avatar answered Mar 12 '26 15:03

Orest Hera



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!