【问题标题】:Capture photos in interval from canvas从画布间隔捕获照片
【发布时间】:2016-04-26 15:14:57
【问题描述】:

我有一个脚本,可以让我在画布中显示网络摄像头并在某些时间间隔内“下载”特定帧。 当时间参数很大(每 2 秒捕获 30 分钟)时,我遇到了麻烦。它可以顺利运行大约 15 分钟,然后崩溃(firefox 因内存不足错误而关闭)。此外,在重新启动 Firefox 后,有时会在 3-4 分钟内拍摄许多 0 字节的照片,然后重新开始工作。我在放置在实验室的旧 2 GB RAM 机器上运行它,有没有办法减少内存使用?

这是一段带有参数和函数realizarCapturas的代码。 我可以添加其余代码,但我认为要优化的部分应该是这个。

  var frecuenciaComienzoCaptura = 1; // how long till next capture
  var frecuenciaCaptura = 3; //seconds between photos
  var duracion = 5; // amount of photos to capture

  function realizarCapturas(){
    var i = 1;
    var interval = setInterval(function(){
      if(i <= duracion){
        context.drawImage(video, 0, 0, 640, 480);

        var imagen = document.getElementById("imagen");
        imagen.href = canvas.toDataURL("image/png");

        var now = new Date();
        var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds());

        imagen.download = filename + ".png"; // Make sure the browser downloads the image
        imagen.click(); // Trigger the click
        i = i+1;
      }else{
        clearInterval(interval);
      }
    }, frecuenciaCaptura * 1000);
  }



  setInterval(function(){
    realizarCapturas();
  }, frecuenciaComienzoCaptura * 1000 * 60 * 60);

  realizarCapturas(); 


}, false);

【问题讨论】:

  • 您可能正在堆积未完成的操作。尝试使用单个 requestAnimationFrame 循环而不是多个间隔进行重构。使用开发工具监控您的资源使用情况。

标签: javascript memory canvas out-of-memory setinterval


【解决方案1】:

作为一项规则,永远不要使用setInterval,因为它可能是调用堆栈溢出的来源,在代码中很难检测到。

您的问题是您没有清除所有正在生成的间隔,因此每 3 秒您正在创建一个新的间隔事件。最终,运行一小段代码所需的时间将超过您创建的所有间隔事件所能管理的时间,因此每个间隔将继续将它们的事件推送到调用堆栈,但不会有机会成为运行直到在堆栈上放置了更多间隔,最终导致崩溃。 setInterval 也不保证事件之间的时间是准确的。

请改用setTimeout。这样,您将只根据需要生成事件,而不必保留句柄来关闭事件。

以下是您编写的代码,这样您就不会出现调用堆栈溢出。

var frecuenciaComienzoCaptura = 1 * 1000* 60 * 60; // how long till next capture
var frecuenciaCaptura = 3 * 1000; //seconds between photos
var duracion = 5; // amount of photos to capture
var counter = 0;
// the capture function
var captura = function () {    
    counter = counter + 1;
    if(counter < duracion){  // do we need more images?
        // only create timer events as needed.
        setTimeout(captura, frecuenciaCaptura); //set time till next image
    }
    context.drawImage(video, 0, 0, 640, 480);
    var imagen = document.getElementById("imagen");
    imagen.href = canvas.toDataURL("image/png");

    var now = new Date();
    var filename = formatNumber(now.getHours()) + "-" + formatNumber(now.getMinutes()) + "-" + formatNumber(now.getSeconds());

    imagen.download = filename + ".png"; // Make sure the browser downloads the image
    imagen.click(); // Trigger the click
}

function realizarCapturas() {
    // request next batch of captures by only creating one timer event as we need
    setTimeout(realizarCapturas,frecuenciaComienzoCaptura);
    counter = 0; // reset counter
    captura(); // capture timages
}

// start captures.
realizarCapturas();

【讨论】:

  • 今天下午似乎工作得很好,内存要求也似乎更容易,因为图像几乎与实际时间同时创建
猜你喜欢
  • 1970-01-01
  • 2011-12-22
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
  • 2020-11-28
  • 2020-07-12
相关资源
最近更新 更多