ianmcgregor Posted February 24, 2014 Share Posted February 24, 2014 Hi, I'm trying to load some images as data URIs (data:image/jpeg;base64,/9j/4AAQSk...) from the browser's localStorage for offline play (my game makes use of dynamic images loaded through a web api). e.g. here: http://codepen.io/ianmcgregor/pen/qkvcj The issue is that the Phaser.Loader.loadFile method always adds a crossOrigin attribute to the image object, which breaks loading data images. If I modify the method as below it fixes it:if(file.url !== null && file.url.indexOf('data:image/') === 0) { file.data.src = file.url;}else { file.data.crossOrigin = this.crossOrigin; file.data.src = this.baseURL + file.url;}Has anyone else come up against this issue and found a way to work around it without modifying the Phaser source code? Ian Link to comment Share on other sites More sharing options...
rich Posted February 24, 2014 Share Posted February 24, 2014 If the image exists in a data URI then you don't need to put it through the Loader at all, you can just insert it directly into the Cache Link to comment Share on other sites More sharing options...
ianmcgregor Posted February 24, 2014 Author Share Posted February 24, 2014 Thanks, I didn't know that was possible. It's working great:var data = new Image();data.src = assets[i].url; // 'data:image/...'game.cache.addImage(assets[i].key, assets[i].url, data); jerome 1 Link to comment Share on other sites More sharing options...
ForgeableSum Posted August 1, 2015 Share Posted August 1, 2015 Thanks, I didn't know that was possible. It's working great:var data = new Image();data.src = assets[i].url; // 'data:image/...'game.cache.addImage(assets[i].key, assets[i].url, data); This works great in Chrome, but it doesn't work at all in Safari. If you check for the image in game.cache._images, the frame object doesn't have the expected width/height (I'm not sure if that causes the problem, or is an effect of the problem, as I don't entirely understand what that property does). At any rate, if you try to create a Phaser.Image with it, the image won't draw to the canvas in Safari. Link to comment Share on other sites More sharing options...
ForgeableSum Posted January 4, 2016 Share Posted January 4, 2016 Yeah, 1 year later and I'm still having the issue. Neither this:var data = new Image();data.src = assets[i].url; // 'data:image/...'game.cache.addImage(assets[i].key, assets[i].url, data);Nor this:var data = new Image();data.crossOrigin = 'anonymous';data.src = assets[i].url; // 'data:image/...'game.cache.addImage(assets[i].key, assets[i].url, data);Nor this:var data = new Image();data.crossOrigin = 'anonymous';data.src = assets[i].url; // 'data:image/...'data.onload = function () {game.cache.addImage(assets[i].key, assets[i].url, data);}Nor this:game.load.image(assets[i].key, assets[i].url); Will work when assets[i].url is an image data URL (base64). I simply can't figure out a way to get an image into the cache this way. Only having this problem in Safari, Chrome is fine. Link to comment Share on other sites More sharing options...
drhayes Posted January 4, 2016 Share Posted January 4, 2016 Try adding an "onload" handler to that image. Inside the onload handler, add the image to the cache. That guarantees that the image is ready and parsed... it has the unfortunate side-effect of making your load async but hopefully that won't be a problem. Link to comment Share on other sites More sharing options...
ForgeableSum Posted January 5, 2016 Share Posted January 5, 2016 Try adding an "onload" handler to that image. Inside the onload handler, add the image to the cache. That guarantees that the image is ready and parsed... it has the unfortunate side-effect of making your load async but hopefully that won't be a problem.So I go through each and every instance of where I load images and do it with onload. I even needed to do it on images loaded the normal way (not as strings but URLs) because those were throwing cross origin errors in safari as well, for whatever reason. It manages to get rid of all the errors in Safari for each image load and leaving me with one simple error: the canvas is tainted, DOM security breach, etc. IF, I don't set crossOrigin to true before adding the src ... all of the images fail to load and throw security errors in Chrome. I've been plagued with these crossOrigin errors since day one. It's like swatting flies. Fix 1 in one browser, 5 more pop up in another. Fix those, and the original fix in the other browser breaks. Finally fix them all and end up with one generic untraceable error... Seriously, this crossOrigin thing makes no sense. I've been studying it and troubleshooting it for over a year now and it still makes no sense. I spend about half of my dev time these days on crossOrigin errors. I'm almost tempted to say "fuck it, I'm supporting Chrome and nothing else." Link to comment Share on other sites More sharing options...
Gob0 Posted January 5, 2016 Share Posted January 5, 2016 Hi, in my mobile apps (Cordova / Javascript / Phaser), i use this CORS policy and i can load / save data image (from a canvas element) without error.<meta http-equiv="Content-Security-Policy" content="default-src 'self' https: http: data: gap: ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; media-src *; connect-src 'self' http://<localip>:<localport>/ http://www.mysite.ch">You can either remove or modify websites http://<localip>:<localport>/ and http://www.mysite.ch Link to comment Share on other sites More sharing options...
ForgeableSum Posted January 8, 2016 Share Posted January 8, 2016 Hi, in my mobile apps (Cordova / Javascript / Phaser), i use this CORS policy and i can load / save data image (from a canvas element) without error.<meta http-equiv="Content-Security-Policy" content="default-src 'self' https: http: data: gap: ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; media-src *; connect-src 'self' http://<localip>:<localport>/ http://www.mysite.ch">You can either remove or modify websites http://<localip>:<localport>/ and http://www.mysite.chSorry, that doesn't do anything. Link to comment Share on other sites More sharing options...
ForgeableSum Posted January 8, 2016 Share Posted January 8, 2016 I've resorted to adding a random number as a URL parameter to each image phaser loads. Basically, I am tricking the browser into thinking that each image it requests is a new image and is not in cache. It's seriously fucked up that I have to do this because it means no browser cache (i.e. longer load time). I am on a very unusual build with AWS S3 and cloudfront - somewhere along the way the images aren't getting the proper cross origin headers. Anyway, safari has a completely different issue. It throws cross origin security errors no matter what I do when the image is a data URI string. Guess I'm not supporting Safari then! Link to comment Share on other sites More sharing options...
Gob0 Posted January 8, 2016 Share Posted January 8, 2016 Finally got a result with your codepen example Try this:game.cache.addImage('image-data', data.src, data); Link to comment Share on other sites More sharing options...
isekream Posted April 26, 2016 Share Posted April 26, 2016 On 8 January 2016 at 6:53 AM, Gob0 said: Finally got a result with your codepen example Try this: game.cache.addImage('image-data', data.src, data); Tried this with let im = new Image(); im.crossOrigin = 'anonymous'; im.onload = function(data){ game.cache.addImage('qr', im.src, im); let qr = game.add.image(game.world.centerX, game.world.centerY, 'qr', 1); qr.anchor.set(0.5); }; im.src = 'https://api.qrserver.com/v1/create-qr-code/?data=' + encodeURIComponent( 'http://' + window.location.hostname + ':3000/mobile.html#' + game.uniqid) + '&size=100x100','QR CODE ' + game.uniqid; but doesn't work.....How did you get it to work? Link to comment Share on other sites More sharing options...
Recommended Posts