1

これは少し根強い問題のようで、多くの人が一度だけ真相を究明したいと思っていると思います。

問題は連鎖の中にある

image = new Image();
image.src = imagePath;

次に一時停止して image.complete を待ちます...

while(HHGimg.height == 0)

また

while(!image.complete)
{
     setTimeout(function(){ foo },100);
}

続いてキャンバスから base64 メソッドへ。

var canvas = document.createElement('canvas');                          
canvas.width = image.width;                                         
canvas.height = image.height;                                           
var canvasContext = canvas.getContext('2d');                            
canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height);  
imageData = canvas.toDataURL('image/jpeg'); 

問題は、image.complete が機能し、有効なオブジェクトがキャンバスに渡されることを確認するための一時停止です。

必要なのは、スクリプトを失速させるループで終了することなく、一時停止が完了するのに十分であることを確認する方法です (この「while」方法のようです)。

続行する前に有効な画像を待つ方法についてのアイデア...

私の全体の機能は次のとおりです...

<script type="text/javascript">
    function imageFetch(imgpath, imgname)                                               
{
    imgdata = "";                                       
    image = new Image();                                                        
    image.src = imgpath + imgname;;                                             
    while(image.height == 0)
    {
            setTimeout(function(){imgdata = "";},100);                                                      
    }
    var canvas = document.createElement('canvas');                          
    canvas.width = image.width;                                         
    canvas.height = image.height;                                           
    var canvasContext = canvas.getContext('2d');                            
    canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height);      
    imgdata = canvas.toDataURL('image/jpeg');                                                   
    return imgdata;                                                             
}
</script>

...しかし、画像が完全にロードされることを確認するための一時停止まで、戻り値の一部は単に「data:,」です。

そして今、あなたに。これを倒す方法についてのアイデアはありますか?

4

2 に答える 2

1

使うだけimage.onload!また、画像が同じドメインからのものである場合にのみ、画像をデータ URL に変換できることも認識する必要があります。そうでない場合は、同じオリジン ポリシー エラーが発生します。また、関数はimage.onloadデータを変換できるようになるまで待機する必要があるため、代わりにコールバックを受け入れるように関数を変更する必要があります。

コードは次のようになります。

<script type="text/javascript">
    function imageFetch(imgpath, imgname, callback)                                               
    {
    var imgdata = "",                                       
    image = new Image();                                                        
    image.src = imgpath + imgname;
    var canvas = document.createElement('canvas');                                     
    var canvasContext = canvas.getContext('2d');                            
    image.onload = function (){                          
        canvas.width = image.width;                                         
        canvas.height = image.height;     
        canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height);      
        imgdata = canvas.toDataURL('image/jpeg');
        callback(imgdata);
    }                          
    return;                                                          
}
</script>

次に、次のように実行します。

imageFetch("/", "random.jpg", function (imgData){
    console.log(imgData);
    // Do whatever you want with imgData here
});

デモを追加しました。オリジン ポリシーが同じであるため、画像には base64 URL を使用していることに注意してください。同じサーバーとポートでホストされている画像は問題なく動作するはずです。

于 2012-08-26T07:32:59.310 に答える
1

画像ローダーを試してみてください。素晴らしいチュートリアルがあります。

与えられたコードは次のとおりです。

  function loadImages(sources, callback) {
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for(var src in sources) {
      numImages++;
    }
    for(var src in sources) {
      images[src] = new Image();
      images[src].onload = function() {
        if(++loadedImages >= numImages) {
          callback(images);
        }
      };
      images[src].src = sources[src];
    }
  }

  window.onload = function(images) {
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    var sources = {
      darthVader: "http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg",
      yoda: "http://www.html5canvastutorials.com/demos/assets/yoda.jpg"
    };

    loadImages(sources, function(images) {
      context.drawImage(images.darthVader, 100, 30, 200, 137);
      context.drawImage(images.yoda, 350, 55, 93, 104);
    });
  };
于 2012-08-26T21:11:17.993 に答える