2017-08-30 1 views
1

Ich verwende Filereader API, um kleine Vorschaubilder von Foto-Uploads anzuzeigen. Ich habe jedoch ein Problem. Wenn Sie wirklich große Bilder hochladen und einige davon hochladen, beginnt es zu verzögern. Die Vorschaubilder sind sehr klein, aber die Dateien sind zu groß. Gibt es eine Möglichkeit, das zu beheben? Hier ist mein 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); 
    } 
}); 

Hier ist eine Geige, wo Sie es testen können: https://jsfiddle.net/snx79yw2/1/.

Zum Beispiel habe ich es mit 6000x4000 Fotos getestet, und wenn es mehr als 4, 5 sind, beginnen sie zu verzögern (und mein PC ist ziemlich anständig, so sollte es nicht so verzögern).

BTW mit Verzögerung Ich beziehe mich auf verlangsamen, einfrieren etc, nicht tatsächliche Verzögerung.

Ich fand this post, aber ich weiß nicht wirklich, wie man die Lösungen von dieser Antwort implementieren kann. Danke im Voraus!

Antwort

1

In diesem Beispiel werden die Bilder mithilfe eines Canvas auf eine maximale Breite von 127 Pixeln verkleinert, bevor sie in der Miniaturbildliste angezeigt werden.

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

Danke, das ist großartig. Ich habe jedoch ein paar Fragen: 1) Ist es möglich, die Skalierungsmethode zu ändern (um Alias ​​zu entfernen)? 2) Ich kann ES6 nicht benutzen, sind Versprechungen wirklich notwendig? Wie kann ich sie umgehen? – nick

+0

2) Ich habe meine Antwort bearbeitet, um einen Rückruf statt eines Versprechens zu verwenden. 1) Wahrscheinlich, aber ich weiß nicht genug über Bildverarbeitung, um hier eine Antwort zu finden. –

+0

Danke, ich habe hier eine Lösung gefunden, also werde ich die beiden mischen! – nick