Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

120
Visualizações
Using drawImage with a video as a source appears to only copy one pixel?

I have a video that's streaming parts of a video into a MediaSource and playing it. I have a canvas that I want to draw the video on an then overlay some effects. However, in my handler, the call to drawImage, while it works, it only appears to copy a single pixel. The video itself plays fine.

I have a screenshot from my app, which has the source video next to the destination canvas element: video and canvas side-by-side

As you can sorta see, the solid color of the canvas is the color of the very first pixel of the source video.

The actual code in question looks similar to this:

  startWatch() {
    this.timer = setInterval(this.copyFrame.bind(this), 1000 / this.fps)
  }

  copyFrame() {
    const { width, height } = this.video.getBoundingClientRect()
    // I've tried the 3, 5, and 9 argument versions of this function
    // width is 300 and height is 168.75.
    this.ctx.drawImage(this.video, 0, 0, width, height, 0, 0, width, height)
  }

(where this.video is a video element)

This code does "work" in that the canvas's color does update over time as the video plays. But it's always just the initial pixel. So the timing loop works, but the drawImage call isn't doing what I expect.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

(1) Using const { width, height } may not be correct. Check the values you are given.
What happens if you console.log the width or height values, are they correct/expected numbers?

(2) "...But the drawImage call isn't doing what I expect."

ctx.drawImage( someElement, 0, 0, A1, A2, 0, 0, B1, B2 );

Consider the above code,

  • The first width/height (A1/A2) is for how much of the input to draw (it must match size of input's own width/height, otherwise cropping or margins will occur). Eg: A1 == 720 if input video is 720 pixels wide.

  • The second width/height (B1/B2) is for how much resize of the output to draw. Usually you want to fill entire canvas area so use canvas dimensions (aspect ratio is left to coder to implement as preferred).

In your shown code, your const { width, height } is either

  • Giving too small a number for A1/A2 params (it samples one pixel)
  • Giving too large a number for B1/B2 params (it stretches output so large that one pixel fills the canvas).

Possible solutions:

Try (if you must use bounding rectangle):

function copyFrame() 
{
    //# width is 300 and height is 168.75.
    //const { width, height } = this.video.getBoundingClientRect()
    
    let myRect = this.video.getBoundingClientRect();
    
    this.ctx.drawImage( this.video, 0, 0, 
                        this.video.videoWidth, this.video.videoHeight, 
                        0, 0, myRect.width, myRect.height);
}

Alternativey you could just draw the picture into canvas size:

function copyFrame() 
{
    //# assuming your Canvas is called "this.cnvs"
    this.ctx.drawImage( this.video, 0, 0, 
                        this.video.videoWidth, this.video.videoHeight, 
                        0, 0, this.cnvs.width, this.cnvs.height);
}

For aspect ratio you can use the below formula (swap all width & height references for a new drawn_width)

myRatio = ( vid_height / vid_width ); 
drawn_height = ( myCanvas_width * myRatio );
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda