1

I have this error

Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0.

It comes only, if i changed the url to a lowerpage like example.com/test when i go back than to the frontpage or something

Or it comes also if you open DevTools on Chrome and simulate a phone or something, reload than and i get this error.

After another reload it works. I dont know why... Everytime the first reload when you entered another page, than it doesnt work. But the 2nd reload than works.

Its a code to pick average color of an image

           var blockSize = 5, // only visit every 5 pixels                   
                defaultRGB = {r:-62,g:-62,b:-62}, // for non-supporting envs                    
                canvas = document.createElement('canvas'),                    
                context = canvas.getContext && canvas.getContext('2d'),                    
                data, width, height,                    
                i = -4,                    
                length,                    
                rgb = {r:-62,g:-62,b:-62},                    
                count = 0;               

            if (!context) {                    
                return defaultRGB;                
            }              

            var imgElReady = false;
            var imgEl = new Image();
            imgEl.onload = function(){
                imgElReady = true;
            }
            imgEl.src = imageurl;

            height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;                
            width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;                
            context.drawImage(imgEl, 0, 0);             

            try {                    
                data = context.getImageData(0, 0, width, height);      
                console.log(data)
                console.log('test1')            
            } catch(e) {       
                console.log('test2')             
                return defaultRGB;                
            }    

            length = data.data.length;               
            while ( (i += blockSize * 4) < length ) {                   
                ++count;                   
                rgb.r += data.data[i];                   
                rgb.g += data.data[i+1];                   
                rgb.b += data.data[i+2];                
            }                
            // ~~ used to floor values                
            rgb.r = ~~(rgb.r/count);                
            rgb.g = ~~(rgb.g/count);                
            rgb.b = ~~(rgb.b/count);                
            return rgb;

On this example, every load when you change the size from normal to simulate a phone or something, the first load jump into console.log test2. And if you reload than again on the same size and page it works

I also checked imgEl after the imgEl.src, an all loads it looks the same and there are images

I know there some other peoples with that bug, but no one has the same problem as my example

The code works only if i load the exact page 2nd time or more. Never on the first load

Reudiga
  • 29
  • 1
  • 4
  • Possible duplicate of [CanvasContext2D drawImage() issue \[onload and CORS\]](https://stackoverflow.com/questions/32880641/canvascontext2d-drawimage-issue-onload-and-cors) – Kaiido Jan 07 '19 at 23:54
  • If sometimes it throws it's because your image has not loaded yet. If othertimes it works it's because your image was cached. – Kaiido Jan 08 '19 at 04:46
  • It doesnt help if i put and jquery update that colors in onload or something... same there – Reudiga Jan 08 '19 at 13:54
  • Everything from `height = canvas.height = imgE...` should be wrapped inside a function that will be set as `imgEl.onload` the line before. Here your image is not loaded => imgEl.width === 0 => canvas.width = 0 and nothing will get drawn on it anyway. – Kaiido Jan 08 '19 at 13:58
  • @Kaiido but why it works on all loads after 2nd time but not on the first load than? What i can change? Also the size is everytime the same. I already tried width and height set to 300x300. Cause thats the size of every image there. But also not working on first load – Reudiga Jan 08 '19 at 14:03
  • This is because the second time the image is cached, so the browser had time to set the image's properties, no network request were required. Now I see the code you gave is actually the body of a function. This means that your function is now asynchronous and can't `return` the result synchronously, so you'll have to [pass a callback](https://jsfiddle.net/hkq85tb3/) or return a Promise if you will. – Kaiido Jan 08 '19 at 14:05
  • If i put `cb(rgb);` instead of return rgb and put that function as callback call i get "illegal break statement" on line cb(rgb) where is return in my example. So also not working :/ – Reudiga Jan 08 '19 at 14:09
  • You saw [my fiddle](https://jsfiddle.net/hkq85tb3/) right? – Kaiido Jan 08 '19 at 14:11
  • @Kaiido thanks for that. I checked, do it same but get "Uncaught SyntaxError: Illegal break statement" on callback(rgb) ... i dont know why :/ I edited your example exactly to my own, it works in fiddle but not in my code :/ – Reudiga Jan 08 '19 at 14:20
  • Then that's up to you to find where you do call `break;` out of a loop. – Kaiido Jan 08 '19 at 14:21
  • @Kaiido no there was no break or something. I dont know. But i do it on another way :) Thank you! I add the colors with jQuery to my HTML instead of callback that :) – Reudiga Jan 08 '19 at 14:37

0 Answers0