来自我的插件的链接: https://github.com/luisdemarchi/cordova-plugin-facedetection-lite
最终代码中的链接: https://github.com/luisdemarchi/example-cordova-facedetection/blob/master/www/index.html
问题: 我正在iOS应用程序(Cordova)中运行JavaScript,当我裁剪具有很多像素的Canvas并将其切成所需的大小时,可以跟上内存增长的速度,直到其限制和应用程序关闭为止。
我在做什么: 我正在创建我的第一个公共存储库,它将成为Cordova的面部检测组件。 C中有一个名为“ pico”的脚本,JavaScript中有一个翻译,我为插件使用了这些库,而在浏览器中,一切都很完美,但是在iOS(我从C库创建了一个库)中,我发生了内存泄漏在C中调用该方法后的几个步骤就会发生这种情况。问题显然出在示例代码中,而不是在库中。
IOS代码流:
我尝试过的事情:
代码
var updateFacePreview = function () {
var loop = function () {
if (faceBox.x > 0) {
var facePreview = document.getElementById("facePreview");
var facePreviewCtx = facePreview.getContext("2d", { alpha: false });
facePreviewCtx.beginPath();
facePreviewCtx.clearRect(0, 0, 400, 400);
// console.log("x: " + parseInt(faceBox.x / scale) + " y: " + parseInt(faceBox.y / scale) + " size: " + parseInt(faceBox.size / scale));
facePreviewCtx.drawImage(
isIosApp ? cameraIosPreview : cameraPreview,
parseInt(faceBox.x / scale),
parseInt(faceBox.y / scale),
parseInt(faceBox.size / scale),
parseInt(faceBox.size / scale),
0,
0,
400,
400
);
delete facePreviewCtx;
delete facePreview;
delete cameraIosPreviewTemp;
cameraIosPreviewTemp = null;
facePreviewCtx = null;
facePreview = null;
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
// window.setTimeout(function () {
// updateFacePreview();
// }, 100);
}
更新:
我发现,如果不更改图像的大小,则在剪切时不会发生内存泄漏。但是,如果放大或缩小1个像素,则会发生泄漏。
这是有效的代码段:
facePreviewCtx.drawImage(
isIosApp ? cameraIosPreview : cameraPreview,
10, 10, 300, 300,
0, 0, 300, 300
);
发生内存泄漏的示例(仅在iOS的UIWebView中运行JS):
facePreviewCtx.drawImage(
isIosApp ? cameraIosPreview : cameraPreview,
10, 10, 300, 300,
0, 0, 150, 150
);
答案 0 :(得分:0)
有效的解决方案:
我正在创建一个临时的HTML Canvas,它会以原始大小捕获人脸而不缩小它,然后仅通过减小大小就为其他HTML Canvas制作了一个切口。
此解决方案不太理想,但是可以避免内存泄漏。以下源代码:
var updateFacePreview = function () {
var loop = function () {
if (faceBox.x > 0) {
var faceSizeOriginal = document.createElement('canvas');
faceSizeOriginal.width = parseInt(faceBox.size / scale);
faceSizeOriginal.height = parseInt(faceBox.size / scale);
var faceSizeOriginalCtx = faceSizeOriginal.getContext("2d", { alpha: false });
faceSizeOriginalCtx.drawImage(
isIosApp ? cameraIosPreview : cameraPreview,
parseInt(faceBox.x / scale),
parseInt(faceBox.y / scale),
parseInt(faceBox.size / scale),
parseInt(faceBox.size / scale),
0,
0,
parseInt(faceBox.size / scale),
parseInt(faceBox.size / scale),
);
facePreviewCtx.drawImage(
faceSizeOriginal,
0, 0, faceSizeOriginal.width, faceSizeOriginal.height,
0, 0, 400, 400
);
cameraIosPreviewTemp = null;
faceSizeOriginal = null;
faceSizeOriginalCtx = null;
facePreview = null;
delete faceSizeOriginalCtx;
delete faceSizeOriginal;
delete facePreview;
delete cameraIosPreviewTemp;
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}