2016-10-31 38 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