2016-10-31 40 views
0

我正在努力完成並理解我編寫的以下'怪物代碼'。基本上,這個函數應該在文件輸入對話框(HTML)被觸發時觸發。但是代碼只能行幾行。它加載圖像,然後在第一個alert()中向我顯示原始圖像的base64,但隨後在代碼中,當實際圖像應該加載到畫布中時,它會返回(在另一個alert())高度0,可能意味着圖像未正確加載或根本沒有加載。顯示圖像的調整大小的Base64輸出

HTML輸入表單(簡體)看起來是這樣的:

<input type='File' accept='image/*' onChange='changeBtn(this);' /> 

及以下功能:

function changeBtn(elem) { 
    selfile = document.getElementById(elem.id); 

    if ('files' in selfile) { 
     var file = selfile.files[0]; 
     if ('name' in file) { 
      str1 = file.name; 
     } 
     if ('size' in file) { 
      str1 += ' (' + ((file.size/1024)/1024).toFixed(2) + 'MB)'; 
     } 
     document.getElementById("label_" + elem.id).innerHTML = str1; 

     var FR= new FileReader(); 
     var img = document.createElement("img"); 
     FR.onload = function(e) { 
      img.src = e.target.result; 
      alert(e.target.result); // Returns B64 of the original image 
     }; 

     FR.readAsDataURL(file); 

     var canvas = document.createElement('canvas'); 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(img, 0, 0); 

     var MAX_WIDTH = 800; 
     var MAX_HEIGHT = 600; 
     var width = img.width; 
     var height = img.height; 
     alert(height); // Returns 0 

     if (width > height) { 
      if (width > MAX_WIDTH) { 
       height *= MAX_WIDTH/width; 
       width = MAX_WIDTH; 
      } 
     } else { 
      if (height > MAX_HEIGHT) { 
       width *= MAX_HEIGHT/height; 
       height = MAX_HEIGHT; 
      } 
     } 
     canvas.width = width; 
     canvas.height = height; 
     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(img, 0, 0, width, height); 

     var dataurl = canvas.toDataURL("image/png"); 
     alert(dataurl); // Returns only "data; " and nothing more 

    } 
} 

預先感謝任何幫助。似乎很簡單,但我不明白。我重寫了代碼至少3次,但總是得到相同的結果。

+0

檢查'img'的範圍。你可以定義它,然後在'onload'之外的地方使用它,它仍然是空的。 –

+0

@ J.Titus但是,當我把所有的東西放在onload中,onload似乎永遠不會完成..(它不顯示提醒) – Fusseldieb

+0

這不是一個範圍界定問題。你可以調用'FR.readAsDataURL(file);'通過向onload發出回調來完成。然而'FR.readAsDataURL(file);'會立即返回,並繼續執行你的代碼,不管'img'變量是否被設置。如果你移動所有在'onload'裏面的'FR.readAsDataURL(file);'的代碼,它應該可以工作。這可能不是最好的方式,但它是一個開始。 – markbernard

回答

1

想通了! 在將圖像加載到它之前,我打電話給FR.readAsDataURL(file);,導致加載一個未定義的文件。

如果我們看一下下面已經失敗代碼:

var FR= new FileReader(); 
var img = document.createElement("img"); 
FR.onload = function(e) { 
    img.src = e.target.result; 
    alert(e.target.result); // Returns B64 of the original image 
}; 
FR.readAsDataURL(file); 

我們現在知道爲什麼。首先調用var FR= new FileReader();,然後調用FR.readAsDataURL(file);,最後在onload觸發時調用:img.src = e.target.result;。這是錯誤的順序。正確的順序是:

function changeBtn(elem) { 
    selfile = document.getElementById(elem.id); 

    if ('files' in selfile) { 
     var file = selfile.files[0]; 
     if ('name' in file) { 
      str1 = file.name; 
     } 
     if ('size' in file) { 
      str1 += ' (' + ((file.size/1024)/1024).toFixed(2) + 'MB)'; 
     } 
     document.getElementById("label_" + elem.id).innerHTML = str1; 

     var FR= new FileReader(); 

     FR.readAsDataURL(file); 

     var img = document.createElement("img"); 
     FR.onload = function(e) { 
      img.src = e.target.result; 
      alert(e.target.result); 

      var canvas = document.createElement('canvas'); 
      var ctx = canvas.getContext("2d"); 

      ctx.drawImage(img, 0, 0); 

      var MAX_WIDTH = 800; 
      var MAX_HEIGHT = 600; 
      var width = img.width; 
      var height = img.height; 
      alert(height); 

      if (width > height) { 
       if (width > MAX_WIDTH) { 
        height *= MAX_WIDTH/width; 
        width = MAX_WIDTH; 
       } 
      } else { 
       if (height > MAX_HEIGHT) { 
        width *= MAX_HEIGHT/height; 
        height = MAX_HEIGHT; 
       } 
      } 
      canvas.width = width; 
      canvas.height = height; 
      var ctx = canvas.getContext("2d"); 
      ctx.drawImage(img, 0, 0, width, height); 

      var dataurl = canvas.toDataURL("image/png"); 
      alert(dataurl); 
     }; 
    } 
} 
+2

幹得好。不要忘記接受你自己的答案。 – markbernard

+0

我會很快做出來的,我只是在我的答案中糾正了一些小的拼寫錯誤。 :) – Fusseldieb