Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用FileReader、图像和<;帆布>;_Javascript_Html5 Canvas_Filereader_Memory Profiling - Fatal编程技术网

Javascript 使用FileReader、图像和<;帆布>;

Javascript 使用FileReader、图像和<;帆布>;,javascript,html5-canvas,filereader,memory-profiling,Javascript,Html5 Canvas,Filereader,Memory Profiling,我正在进行图像多上传,听起来不错,但是。。一如既往的内存问题 脚本的目标是在上传100多个图像(300Mb+)后生存下来。因此,如果您发现(我仍然是javascript跛脚)任何问题,请给我一个建议。谢谢 我的代码: CFileReader.prototype.proccessFile = function(cb) { // this means File var reader = new FileReader(); reader.readAsDataURL(this);

我正在进行图像多上传,听起来不错,但是。。一如既往的内存问题

脚本的目标是在上传100多个图像(300Mb+)后生存下来。因此,如果您发现(我仍然是javascript跛脚)任何问题,请给我一个建议。谢谢

我的代码:

CFileReader.prototype.proccessFile = function(cb) {
    // this means File
    var reader = new FileReader();
    reader.readAsDataURL(this);
    reader.onload = (function (f) { 
        return function(e) {
            var image = new Image();
            image.src = e.target.result;
            image.onload = (function(f) {
                return function() {
                    var maxWidth = 700,
                        maxHeight = 700,
                        imageWidth = this.width,
                        imageHeight = this.height;

                    if (imageWidth > imageHeight) {
                      if (imageWidth > maxWidth) {
                        imageHeight *= maxWidth / imageWidth;
                        imageWidth = maxWidth;
                      }
                    }
                    else {
                      if (imageHeight > maxHeight) {
                        imageWidth *= maxHeight / imageHeight;
                        imageHeight = maxHeight;
                      }
                    }
                    var canvas = document.createElement('canvas');
                    canvas.width = imageWidth;
                    canvas.height = imageHeight;

                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
                    if(typeof cb == 'function') {
                        cb(f,canvas.toDataURL());
                    }
                    delete canvas;
                    delete ctx;
                    return;
                }
            })(f);

        };
    })(this);    
}

好吧,那就用几天的谷歌搜索,用几个小时寻找最佳解决方案。(不是有史以来最好的,而是最好的一个,我可以吹嘘出来)。如果有人有更好的,把它的答案,或只是给坏名声

目标一: 在全局空间中存储所有内容(画布、阅读器、画布上下文、图像)

目标二: 使用canvas.toBlob方法(目前仅在Firefox中实现,需要一些polyfill)

目标三: 再加上一些等待,我不能简单地解释,这只是经验。目标是,允许浏览器在调用之间调用垃圾收集器

这是我最后一个开发脚本:

window.prepareFile = function (index,cb) {
    // this means file html element
    var res = window.configuration.photo.resolution.split(":");

    //var res = [300,200];
    var reader = window.reader;
    $('#fm-up-status > tr[for="'+this.files[index].name+'"]').children('td')[3].innerHTML = 'Zpracovávám';
    reader.readAsDataURL(this.files[index]);
    reader.onload = (function (f) { 
        return function(e) {
            setTimeout(function(){
                var image = window.image;
                image.src = e.target.result;
                image.onload = (function(f) {
                    return function() {
                        var maxWidth = parseInt(res[0]),
                            maxHeight = parseInt(res[1]),
                            imageWidth = this.width,
                            imageHeight = this.height;
                        if (imageWidth > imageHeight) {
                            if (imageWidth > maxWidth) {
                              imageHeight *= maxWidth / imageWidth;
                              imageWidth = maxWidth;
                            }
                        }
                        else {
                            if (imageHeight > maxHeight) {
                              imageWidth *= maxHeight / imageHeight;
                              imageHeight = maxHeight;
                            }
                        }
                        var canvas = window.canvas;
                        canvas.width =0;
                        canvas.width = imageWidth;
                        canvas.height = imageHeight;
                        window.ctx.drawImage(this, 0, 0, imageWidth, imageHeight);
                        canvas.toBlob(
                            function (blob) {
                                var formData = new FormData();

                                formData.append('file', blob, f.name);
                                cb(f.name,formData);
                            },
                            'image/jpeg'
                        );
                        return;
                    }
                })(f);
                return;
            },500);
        };
    })(this.files[index]);

    return;
}
然后,您可以简单地将数据上传为标准格式(多路径),如下所示:

window.uploader = function(filename,formdata,cb) {

    $('#fm-up-status > tr[for="'+filename+'"]').children('td')[3].innerHTML = 'Uploaduji';
    xhr = jQuery.ajaxSettings.xhr();
    if (xhr.upload) {
        xhr.upload.addEventListener('progress', function (evt) {
            if (evt.lengthComputable) {  
                var floatComplete = evt.loaded / evt.total;
                window.uploadProgress(filename,floatComplete);

            }
        }, false);
    }  
    provider = function () {
        return xhr;
    };    
    $.ajax({
        url: window.uploadUri,
        type: "POST",
        data: formdata,
        xhr: provider,
        processData: false,
        contentType: false,
        dataType: "json",
        success: function (res,state,xhr) {
            cb(false,res,xhr);
            return;
        },
        error: function (xhr, state, err) {
            cb(err,false,xhr)
            return;
        }
    });    
};

这段代码实际上还不适合生产,它只是一个简单的概念证明,我认为window.createObjectURL比FileReader快,您应该使用这两种方法,并为FileReader提供回退功能……此外,您还可以检查每个操作的性能,因为每个浏览器都有差异,例如 别忘了出于记忆的原因撤销ObjectURL…你也可以选择你的网络工作者


你正在上传到服务器吗?还是仅仅使用客户端的图像?只是因为我没有看到任何服务器通信正在进行..我正在上传它们。上传脚本是在回调中,将这个加载脚本分离到自己的作用域是一个很好的举动,它节省了大量内存。但仍然存在问题,进程线程仍然提交超过1,2G的ram。请尝试使用内存探查器查看哪些对象泄漏内存:我怀疑创建的
元素的GC处理速度不够快,您在这里无能为力。但我假设内存配置文件与可用RAM较少的系统不同。如果RAM是免费的,浏览器会使用它。谢谢Mikko的建议。但这并不像你写的那样简单。我已经将映像异步onload事件分离到分离的作用域中,然后垃圾收集器变得疯狂,并将线程保持在可用ram提交值(debian标准Overmit值)上。似乎是(function(){})(scope);这将是一个对javascript中所有内容的关注。附言:200张图片中有180张(1.7GB)在多次上传后幸存下来。。我认为,对于第一个alpha版本来说,这真的是一个很好的结果\
window.uploader = function(filename,formdata,cb) {

    $('#fm-up-status > tr[for="'+filename+'"]').children('td')[3].innerHTML = 'Uploaduji';
    xhr = jQuery.ajaxSettings.xhr();
    if (xhr.upload) {
        xhr.upload.addEventListener('progress', function (evt) {
            if (evt.lengthComputable) {  
                var floatComplete = evt.loaded / evt.total;
                window.uploadProgress(filename,floatComplete);

            }
        }, false);
    }  
    provider = function () {
        return xhr;
    };    
    $.ajax({
        url: window.uploadUri,
        type: "POST",
        data: formdata,
        xhr: provider,
        processData: false,
        contentType: false,
        dataType: "json",
        success: function (res,state,xhr) {
            cb(false,res,xhr);
            return;
        },
        error: function (xhr, state, err) {
            cb(err,false,xhr)
            return;
        }
    });    
};
    if("createObjectURL" in window || "URL" in window && 
    "createObjectURL" in window.URL || "webkitURL" in window && 
    "createObjectURL" in window.webkitURL) { 
        if("createObjectURL" in window) { 
            // Chrome exposes create/revokeObjectURL directly on window 
            objURL = window.createObjectURL(file); 
        } else if("webkitURL" in window) { 
            // Chrome exposes create/revokeObjectURL on the new  webkitURL API 
            objURL = window.webkitURL.createObjectURL(file); 
        } else { 
            // FF4 exposes create/revokeObjectURL on the new URL API 
            objURL = window.URL.createObjectURL(file); 
        } 

        // RESIZE image 
        // STORED IN    
        // objURL
} else { 
    // fallback to FileReader for FF3.6             
    reader = new FileReader();
    reader.onload =  function(event) {                                                                  
        // RESIZE image 
        // STORED IN    
        // event.target.result                 
    }

    reader.onprogress = function (evt) {
       if (evt.lengthComputable) {
            var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
            console.log(percentLoaded);
       }
    }
    reader.readAsDataURL(file);                                                                 
}