2016-10-31 2 views
0

나는 내가 작성한 다음과 같은 'monstercode'를 성취하고 이해하기 위해 열심히 노력하고 있습니다. 기본적으로 파일 입력 대화 상자 (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 그러나 온로드 내부에 모든 것을 넣으면 온로드가 완료되지 않는 것처럼 보입니다. (알림이 표시되지 않습니다.) – 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