在处理数据之前加载图像并等待image.complete

时间:2012-08-26 00:19:46

标签: image base64 html5-canvas settimeout

这似乎是一个长期存在的问题,我认为很多人都希望一劳永逸地找到底线。

问题存在于

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

然后暂停等待image.complete,例如......

while(HHGimg.height == 0)

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

后面是canvas到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完成其工作并将有效对象传递给画布。

我们需要的是一种方法,以确保暂停足以完成而不会停止一个停止脚本的循环(这种“同时”方法似乎)

有关如何在继续之前等待有效图片的任何想法...

我的整个功能如下......

<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:,”

现在结束了。关于如何打败这个的任何想法?

2 个答案:

答案 0 :(得分: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
});

我添加了demo。请注意,由于相同的源策略,我在那里使用base64 URL作为图像。托管在同一服务器和端口上的图像应该可以正常工作。

答案 1 :(得分:1)

尝试图像加载器 - 这是一个很棒的tutorial

以下是给出的代码:

  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);
    });
  };