2013-05-07 49 views
9

的jsfiddle網址:http://jsfiddle.net/Xotic750/AjtLx使用readAsDataURL()用於圖像預覽

這方面的工作了一整天,我看不到的問題。這可能是由於我對FileReader對象的工作原理的狹隘理解,但我想要做的是使用readAsDataURL()獲取用戶選擇的圖像,並在屏幕上的表格中預覽它們。一切都在努力減去......你猜對了......預覽......很好。我認爲我很近,因爲預覽會起作用,但它只顯示該集合的最後一個圖像。比如說,如果我上傳了6張圖像,那麼第一行的3張圖像就會被打破,第二行的第2張會被打破,然後最後的第6張圖像會顯示預覽....任何建議非常感謝。此外,一旦這個作品它可能會幫助別人努力,因爲我已經找遍了一個解決這個問題,我似乎無法挖什麼後做同樣的事情....

function PreviewImages() { 
    var inputID = document.getElementById('input_clone'); 
    var totalImages = inputID.files.length; 
    var imagesPerRow = 3; 
    var numRows = totalImages/imagesPerRow; 
    var row = ""; 
    var cell = ""; 
    var element1 = ""; 
    var elementID = ""; 


    for(var i = 0; i < numRows; i++){ //create rows 
     row = document.getElementById('image_preview_table').insertRow(i); 
     for(var ii = 0; ii < imagesPerRow; ii++){ //create cells 
      cell = row.insertCell(ii); 
      elementID = "img_" + ii; 
      element1 = document.createElement("img"); 
      element1.name = elementID; 
      element1.id = elementID 
      cell.appendChild(element1); 

      oFReader = new FileReader(); 

      oFReader.onload = function(oFREvent){ 
       var dataURI = oFREvent.target.result; 
       var image = document.getElementById(elementID); 
       image.src = dataURI; 
      }; 

       oFReader.readAsDataURL(document.getElementById("input_clone").files[ii]); 

    } 
} 
} 

回答

10

這裏是一種解決方案,您可能會注意到,您的原創作了相當多的調整以使其起作用。

CSS

div.rounded { 
    width: 100%; 
    border-style: solid; 
    border-width: 1px; 
    border-radius: 5px; 
} 
label { 
    display: block; 
} 
input { 
    display: block; 
} 
#previewTable { 
    width: 100%; 
} 

HTML

<div id="imagesDiv" class="rounded"> 
    <label for="chooseFiles">Add Images</label> 
    <input type="file" id="chooseFiles" multiple="multiple" /> 
    <table id="previewTable"> 
     <thead id="columns"></thead> 
     <tbody id="previews"></tbody> 
    </table> 
</div> 

的Javascript

(function (global) { 
    var imagesPerRow = 3, 
     chooseFiles, 
     columns, 
     previews; 

    function PreviewImages() { 
     var row; 

     Array.prototype.forEach.call(chooseFiles.files, function (file, index) { 
      var cindex = index % imagesPerRow, 
       oFReader = new FileReader(), 
       cell, 
       image; 

      if (cindex === 0) { 
       row = previews.insertRow(Math.ceil(index/imagesPerRow)); 
      } 

      image = document.createElement("img"); 
      image.id = "img_" + index; 
      image.style.width = "100%"; 
      image.style.height = "auto"; 
      cell = row.insertCell(cindex); 
      cell.appendChild(image); 

      oFReader.addEventListener("load", function assignImageSrc(evt) { 
       image.src = evt.target.result; 
       this.removeEventListener("load", assignImageSrc); 
      }, false); 

      oFReader.readAsDataURL(file); 
     }); 
    } 

    global.addEventListener("load", function windowLoadHandler() { 
     global.removeEventListener("load", windowLoadHandler); 
     chooseFiles = document.getElementById("chooseFiles"); 
     columns = document.getElementById("columns"); 
     previews = document.getElementById("previews"); 

     var row = columns.insertRow(-1), 
      header, 
      i; 

     for (i = 0; i < imagesPerRow; i += 1) { 
      header = row.insertCell(-1); 
      header.style.width = (100/imagesPerRow) + "%"; 
     } 

     chooseFiles.addEventListener("change", PreviewImages, false); 
    }, false); 
}(window)); 

jsfiddle

+0

不錯!似乎工作得很好,但在Firefox中遇到問題。 – commanderZiltoid 2013-05-08 03:13:04

+1

我自己看了看,發現了問題。第二個參數實際上在'removeEventListener'中不是可選的。 Chrome顯然不抱怨,但Firefox。修改小提琴可以在http://jsfiddle.net/6cgTj/23/找到。 – 2013-05-08 03:59:38

+1

@Ray Nicholas,是的,這是Firefox的問題。我已更新,所有應該工作。 – Xotic750 2013-05-08 10:52:20

10

與您的代碼的問題是:readAsDataURL()是異步的,您應該等到完成讀取之後再調用第二次讀取或通過調用新的FileReader()來創建新實例。

Xotic750的答案是有效的,因爲他爲每個圖像創建一個FileReader,而只使用一個FileReader。因爲FileReader.readAsDataURL()將整個圖像轉換爲一個大字符串(以「data:image/jpeg; base64,/ 9j/4SVaRXhpZgAAS」的形式),所以使用FileReader預覽圖像並不是一個好的選擇。 .....「),並且通過將整個圖像數據串放入img.src屬性來顯示圖像,如果圖像很大,則會冒內存不足的風險。儘管您可以通過img.src =「data:image/jpeg;」指定包含整個圖像數據的url,但是img.src是爲了包含圖像的url而不是圖像的數據。 ...「。

所以,你應該用window.URL.createObjectURL()創建一個URL引用您的本地圖片,並指定URL以便img.src:

... 
img.src = window.URL.createObjectURL(fileInput.files[i]); 
... 
+0

感謝您指出dataUrl和的疑難雜症,一直在努力與預覽凍結UI加載中等大的圖像(> 200kb) – 2017-12-02 05:37:52