从 canvas 间隔拍摄照片
Capture photos in interval from canvas
我有一个脚本,可以让我在 canvas 网络摄像头和 'download' 特定帧中显示特定的帧。
当时间参数很大时(每 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);
通常永远不要使用 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();
我有一个脚本,可以让我在 canvas 网络摄像头和 'download' 特定帧中显示特定的帧。 当时间参数很大时(每 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);
通常永远不要使用 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();