2017-08-30 4 views
1

私はFilereader APIを使用して、写真アップロードの小さなサムネイルを表示しています。しかし、私は問題があります。あなたが本当に大きな画像をアップロードし、それらのいくつかをアップロードすると、遅れが始まります。サムネイルは実際には小さいですが、ファイルが大きすぎます。これを修正する方法はありますか?ここに私のjavascriptだ:Filereader image thumbnail lags

document.querySelector('input').addEventListener('change', function(e){ 
    var files = e.target.files; 

    for(var i = 0; i < files.length; i++){ 

    var f = files[i]; 
    var reader = new FileReader(); 

    reader.onload = (function(tf){ 
     return function(evt){ 
     document.querySelector('.thumbs').innerHTML += '<div class="thumb" style="background-image: url('+evt.target.result+')"></div>'; 
     } 
    })(f); 

    reader.readAsDataURL(f); 
    } 
}); 

ここであなたがそれをテストすることができますフィドルです:https://jsfiddle.net/snx79yw2/1/

たとえば、私は6000x4000の写真でテストしました.4,5以上になると、遅くなり始めました(私のPCはまあまあですので、遅れてはいけません)。

遅れを伴うBTW実際の遅れではなく遅い、凍結などを指します。

私はthis postを見つけましたが、実際にその解決策から解決策を実装する方法はわかりません。あらかじめThx!

答えて

1

この例では、画像をサムネイルリストに表示する前にキャンバスを使用して最大幅127pxまで画像のサイズを変更しています。

document.querySelector('input').addEventListener('change', function(e){ 
 
    var files = e.target.files; 
 
    for(var i = 0; i < files.length; i++){ 
 
    var f = files[i]; 
 
    var reader = new FileReader(); 
 

 
    reader.onload = (function(tf) { 
 
     return function(evt) { 
 
     // resize the image before using the resolved dataURL to set the thumbnail src 
 
     resize(evt.target.result, 127, function(dataURL) { 
 
      document.querySelector('.thumbs').innerHTML += `<img class="thumb" src="${dataURL}" />`; 
 
     }); 
 
     } 
 
    })(f) 
 

 
    reader.readAsDataURL(f); 
 
    } 
 
}); 
 
/** 
 
* usage resize(dataURL:src, int:maxWidth, function:callback) 
 
*/ 
 
function resize(src, maxWidth, callback) { 
 
    var img = document.createElement('img'); 
 
    img.src = src; 
 
    img.onload =() => { 
 
     var oc = document.createElement('canvas'); 
 
     var ctx = oc.getContext('2d'); 
 
     // resize to [maxWidth] px 
 
     var scale = maxWidth/img.width; 
 
     oc.width = img.width * scale; 
 
     oc.height = img.height * scale; 
 
     ctx.drawImage(img, 0, 0, oc.width, oc.height); 
 
     // convert canvas back to dataurl 
 
     callback(oc.toDataURL()); 
 
    } 
 
}
.thumbs{background: #222;border-radius: 5px;white-space: nowrap;overflow-x: scroll;padding: .25rem;} 
 
.thumb{height: 3rem;width: 3rem;border-radius: 3px;background-size: cover;background-position: center center;background-repeat: no-repeat;display: inline-block;margin: .25rem .25rem calc(.25rem - 4px);}
<input type="file" multiple /> 
 
<div class="thumbs"></div>

+0

おかげで、これは素晴らしいです。私はいくつかの質問があります:1)スケーリングの方法を変更することは可能ですか(エイリアシングを削除するため)? 2)私はES6を使用することはできません、約束は本当に必要ですか?どうすればそれらを回避できますか? – nick

+0

2)約束の代わりにコールバックを使用するように私の答えを編集しました。 1)おそらく、私はここで答えを出すことができるように画像処理について十分に知りません。 –

+0

ありがとう、私はここに1つの解決策を見つけたので、私は2つを混ぜるつもりです! – nick