简体   繁体   中英

Internet Explorer 9 sometimes draws blank images on canvas

I have a web application that generates images on the fly and then renders (segments of) them on the client using canvas - the general code looks something like this (simplified)...

var width = ...
var height = ...
var img = new Image();
img.onload = function(){ // Set onload before setting image source ;)
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  context.drawImage(this,0,0,width,height,0,0,width,height);
}
img.src = ...

In firefox and chrome, this works fine. In IE9 (and sometimes IE10), this sometimes results in a blank image. As a workaround, I put in...

var width = ...
var height = ...
var img = new Image();
img.onload = function(){
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  window.setTimeout(function(){
    context.drawImage(img,0,0,width,height,0,0,width,height);
  }, 10); // 10 millisecond delay here seems to give IE time to make sure the image is actually ready
}
img.src = ...

Obviously, putting in random delays is making me nervous - I would much rather figure out why this happens. Is there another event type / method / property on images that may be used? Could there perhaps be something in the http headers sent down with the images / the encoding / transfer method that is causing this?

Since drawing images on the canvas seems to be something that trips up new users a lot, searches mostly yield instances where the developer set the source before the onload method. The closest other question / reply I was able to find was this : https://stackoverflow.com/a/15186350/470062

Edit:

I have updated the examples to include width and height definitions at the start

Edit 29/Apr/2013:

The 10 millisecond delay is not always sufficient - I have changed the code to check the canvas pixels to determine if anything has been drawn - This feels like such an ugly hack though - I would love to know if there is a better way :

... snip - this is at the end of the image load callback..

if((navigator.appVersion.indexOf("MSIE")) >= 0){    

    function checkAndRedraw(){
        context.clearRect(0,0,width,height);
        context.drawImage(img, 0, 0, width, height);
        var imageData = context.getImageData(0, 0, width, height),
        data = imageData.data,
        len = data.length;

        for (var i = 0; i < len; i += 4){
            if(data[i] || data[i+1] || data[i+2]){
                scheduleRedraw = null; // prevent memory leak
                return; // A pixel contained some non empty value so something was drawn - done.
            }
        }

        scheduleRedraw();
    }
    var redrawHackTimeout;
    function scheduleRedraw(){
        window.clearTimeout(redrawHackTimeout);
        redrawHackTimeout = window.setTimeout(checkAndRedraw, 500);
    }

    scheduleRedraw();
}
//END IE9 Hack

I have the same issue in IE9, what I had to do is this too:

            theImage = new Image();

    theImage.onload = function() {
        that = this;
        setTimeout(function() {
            that.onload2();
        }, 100);
    };


    theImage.onload2 = function(){
               #your old load function code
            }

            theImage.src = 'http://....';

I don't understand why ie9 triggers load image function when it's not actually loaded or not "usable" yet in a canvas. it makes me pull my hair out.

var img = new Image();

img.onload = function(){ // Set onload before after setting image source ;)
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  context.drawImage(this,0,0,width,height,0,0,width,height);
}

You must set the src , then wait for the image to load.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM