Reputation: 12904
I am taking list of files dropped in the area. and then getting their dataUrl and putting them in an Img. and then putting that image in canvas using drawImage
. I do appropriate scaling of images according to their size. Its functioning properly. But the problem is even after the operation is complete. e.g. long after Canvas's have been appended to the dom CPU and memory usage goes high. just to show the canvas's it takes high CPU and memory.
Code inside drop event:
e.preventDefault();
$("#controller_search").attr('value', '^')
$("#controller_search").attr('disabled', 'disabled');
$("#imageList").html('');
var templateData = "\
<div class='imageviewer-up'> \
<div class='curtain'></div> \
<canvas class='canvas'></canvas> \
<div class='loading'>0%</div> \
</div> \
";
for(var i=0;i<event.dataTransfer.files.length;++i){
var file = event.dataTransfer.files[i];
var reader = new FileReader();
reader.onload = (function(file){
return function(e){
var template = $(templateData);
var image = new Image();/*template.find('img')[0];*/
image.onload = (function(image){
return function(){
var size = {height: image.height, width: image.width}
var rSize = size;
if(size.height > 175)
rSize = {height: 175, width: (175*size.width)/size.height}
else{
rSize = {height: 175/(size.width/size.height), width: size.width/(size.width/size.height)}
}
image.height = rSize.height;
image.width = rSize.width;
var canvas = template.find('canvas')[0];
var context = canvas.getContext("2d");
context.mozImageSmoothingEnabled = true;
canvas.height = 175+4;
canvas.width = image.width+4;
context.drawImage(image, (canvas.height-image.height)/2, 2, image.width, image.height);
template.css('height', 175+4+0);
template.css('width', image.width+0);
}
})(image)
image.src = e.target.result;
image.title = file.name;
console.log(file.name);
$("#imageList").append(template);
image = null;
}
})(file);
reader.readAsDataURL(file);
}
Currently I am testing by dragging 20 Images (sums up to 45 MB) so 20 canvas gets created. Is that too much ?
EDIT
I've even tested using IMG instead of canvas. e.g. using IMG with dataUrls only. But this way too. slows down in the same way. So is there any memory leak in my code ?
Upvotes: 4
Views: 2662
Reputation: 12904
I think It is a problem regarding chrome bug#36412
The data:
url is taking up memory but not releasing that. and thats causing the potential problem. I fixed it using window.URL.createObjectURL
and window.URL.revokeObjectURL
. for webkit its window.webkitURL
instead. Now its working fine even with 30+ Images. Current code looks like:
for(var i=0;i<event.dataTransfer.files.length;++i){
var file = event.dataTransfer.files[i];
var total = event.dataTransfer.files.length;
var template = $(templateData);
var image = new Image();/*template.find('img')[0];*/
image.onload = (function(image, template, i){
return function(e){
/* Size adjustment */
var canvas = template.find('canvas')[0];
var context = canvas.getContext("2d");
context.drawImage(image, (canvas.height-image.height)/2, 2, image.width, image.height);
window.URL.revokeObjectURL(this.src);
}
})(image, template, i)
image.src = window.URL.createObjectURL(file);
bong.upload.files.push(file);
$("#imageList").append(template);
image = null;
}
Upvotes: 4