2017-06-06 4 views
0

私は現在、ユーザーが複数の画像をアップロードして同時に使用できるアプリケーションを構築しています。一部のプロセスは大きなイメージファイルのためにパフォーマンスが悪いため、ユーザーが取得する前にサイズを変更する必要があります。img.onloadで関数を返す方法は?

私のresizer()では、キャンバスを使用してサイズを変更しようとしています。それは動作しますが、 'canvas.toDataURL()'はimg.onload関数の中にあるので、値を返す方法とそれをhandleFiles()関数に解析する方法はわかりません。

も...私はhandleFiles()からいくつかのコード取得した場所にいくつかの例を試みた - のような:

var preview = document.getElementById("img"+count); 
var surface = document.getElementById("cubface"+count); 
var count = counterImg(); 
preview.src = resizer(e.target.result, count); 
surface.src = resizer(e.target.result, count); 

をそして

var preview = document.getElementById("img"+number); 
var surface = document.getElementById("cubface"+number); 
preview.src = canvas.toDataURL; 
surface.src = canvas.toDataURL; 

私のようimg.onload関数の最後に入れてリサイズを得ましたが、処理されるループの最後の画像しか得られませんでした。

だから、質問は以下のとおりです。resizer()機能で

  1. img.onloadであるcanvas.toDataURL値を返す方法?

  2. なぜループは最後のインスタンスのみをカバーし、すべてのイメージではなく、それを解決するのでしょうか?

全コード:

はJavaScript:

function resizer(base64, number){ 

    // Max size for thumbnail 
    if(typeof(maxWidth) === 'undefined') maxWidth = 1200; 
    if(typeof(maxHeight) === 'undefined') maxHeight = 1200; 

    var img = new Image(); 
    img.src = base64; 

    // Create and initialize two canvas 
    var canvas = document.createElement("canvas"); 
    var ctx = canvas.getContext("2d"); 
    var canvasCopy = document.createElement("canvas"); 
    var copyContext = canvasCopy.getContext("2d"); 

    img.onload = function() { 

     // Determine new ratio based on max size 
     var ratio = 1; 
     if (img.width > maxWidth) 
      ratio = maxWidth/img.width; 
     else if (img.height > maxHeight) 
      ratio = maxHeight/img.height; 

     // Draw original image in second canvas 
     canvasCopy.width = img.width; 
     canvasCopy.height = img.height; 
     copyContext.drawImage(img, 0, 0); 

     // Copy and resize second canvas to first canvas 
     canvas.width = img.width * ratio; 
     canvas.height = img.height * ratio; 
     ctx.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height); 

     return canvas.toDataURL(); 

    }; 

    return img.onload; 

} 


function handleFiles(files) { 
    for (var i = 0; i < files.length; i++) { 
     var file = files[i]; 
     var count = counterImg(); 
     var preview = document.getElementById("img"+count); 
     var surface = document.getElementById("cubface"+count); 

     var reader = new FileReader(); 
     reader.onload = (function (preview, surface) { 
      return function (e) { 
       var newimage = resizer(e.target.result, count); 
       preview.src = newimage; 
       surface.src = newimage; 
       $('#image-cropper'+count).cropit('imageSrc', e.target.result); 
      } 
     })(preview, surface); 
     reader.readAsDataURL(file); 
    } 
} 
+0

あなたは確かで$( '#イメージ・クロッパーということです'+ count)変数の数は適切にスコープされていますか?関数(プレビュー、サーフェス)に追加することができます。 – user3220633

+0

それはちょうどこの関数です: 'var j = 0; function counterImg(){ j ++; return j; } ' – PLAYCUBE

答えて

1

変数countが正しくスコープされていません。

関数を宣言してから使用するまでに時間がかかるため、各実行は同じ値で終了します。したがって、jqueryセレクタは常に同じ要素を返します。これは、最後の画像だけが変更された理由を説明します。

ここに実行を示すjsfiddleがあります。

https://jsfiddle.net/Lc6bngv5/1/

これを修正するには、単にあなたのプレビューと表面をカプセル化する関数に通過回数:

reader.onload = (function (preview, surface, count) { 
     return function (e) { 
      var newimage = resizer(e.target.result, count); 
      preview.src = newimage; 
      surface.src = newimage; 
      $('#image-cropper'+count).cropit('imageSrc', e.target.result); 
     } 
    })(preview, surface, count); 

を2番目の質問について:

リサイズ機能は、関数を返します。その関数の結果は返されません。適切にURLを取得するには、私は、コールバック関数を使用します。

reader.onload = (function (preview, surface, count) { 
    return function (e) { 
     var newimage = resizer(e.target.result, count, function(url){ 
      preview.src = url; 
      surface.src = url; 
      $('#image-cropper'+count).cropit('imageSrc', e.target.result); 
     }); 
    } 
})(preview, surface, count); 

そして、あなたは、サイズ変更中に以下の変更を行う必要があります:

function resizer(base64, number, cb){ 
    ... 
    img.onload = function() { 
     ... 
     // return canvas.toDataURL(); 
     cb(canvas.toDataURL()); 
    }; 
} 
+0

うわー、あなたのアドバイスありがとう!これは第2の問題を解決しました。どのように 'img.onload'で返り値を作るか考えていますので、' canvas.toDataURL(); 'と' handeFiles() 'を解析できますか? – PLAYCUBE

+1

編集を追加しました。コールバック関数を使用すると、結果を適切に取得できます。 – user3220633

+0

ありがとう!それは最高だった! – PLAYCUBE

関連する問題