[SOLVED] Load external sprites from an URL

Hi to all,
i just started programming in cocos2d-html5 and i was wondering how can i load sprites from an external url (such as facebook friends’ profile images)
Thanks

I’ve tried:

var myUrl = “http://externalurl.com/image.png”;
var text = cc.TextureCache.getInstance().addImage(myUrl);
this.sprite.setTexture(tex);

but i get this error:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.

I don’t think it’s impossible to load external images. How can i get around this?
Thanks

Hi,MadBit Entertainment.
You can try it like that:

var imageUrl = "http://files.cocos2d-x.org/images/orgsite/logo.png";
        var image = new Image();
        image.src = imageUrl;
        var self = this;
        image.addEventListener('load',function(){
            cc.TextureCache.getInstance().cacheImage(imageUrl, image);
            var sprite = cc.Sprite.create(imageUrl);
            self.addChild(sprite);
        },false);

This way only work on cocos2d-html5 ,it can not work on javascript binding.

Thanks Xingsen, unfortunately i get this error:

Uncaught SecurityError: An attempt was made to break through the security policy of the user agent. CCTexture2D.js:504
cc.Texture2DWebGL.cc.Class.extend.handleLoadedTexture CCTexture2D.js:504
cc.TextureCache.cc.Class.extend.cacheImage CCTextureCache.js:450
(anonymous function)

I’ve tried it both in local and into a webserver. but if i try to load external url files i get that error, instead works when i try to load resources in my domain, but i have to load profile pictures of facebook users.

Hi
Did you solve this problem?

Hi,

It’s a cross domain security policy that forbid your action in WebGL, when the target server doesn’t allow cross origin usage, WebGL will throw this error.
Maybe you can try to retrieve that image from your server script, and then send it from your own server, that should work.

Huabin

See the WebGL Specification here: http://www.khronos.org/registry/webgl/specs/latest/1.0/
Goto section “4.2 Origin Restrictions”

Can provide sample code?

Code like this?

sendRequest: function(key,data) {
var that = this;
var xhr = new XMLHttpRequest();
cc.log(key);
cc.log(GlobalDef.SERVER_URL);
cc.log(data);
xhr.open(“POST”, GlobalDef.SERVER_URL,true);
xhr.onreadystatechange = function() {
if(xhr.readyState 4 && xhr.status 200){
var result = xhr.responseText;
var image = new Image();
??????????
}
}
xhr.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”);
xhr.send(data);
}

If create sprite from my server url ,It can work?

Hi, max

If the image url is from the same domain of your page, there won’t be any problem.

Huabin

Hi Huabin
But I need to get pictures from other websites and show in app. and support cross plateform.

Can you give me some suggest or sample code? Thanks you !

Huabin LING wrote:

Hi,
>
It’s a cross domain security policy that forbid your action in WebGL, when the target server doesn’t allow cross origin usage, WebGL will throw this error.
Maybe you can try to retrieve that image from your server script, and then send it from your own server, that should work.
>
Huabin

That’s what I can figured out for now, maybe someone else have better solutions, don’t hesitate to tell the community.

Hi,

I am having the same issue as MadBit Entertainment with both different codes…
What is interesting is that :

  • with the exact same web server setup

  • with the exact same remote image url
    this code (using jquery) simply embedded in a webpage works fine :

    var img = $("").attr(‘src’, myimage.url)
    .load(function() {
    if (!this.complete || typeof this.naturalWidth == “undefined” || this.naturalWidth == 0) {
    alert(‘broken image!’);
    } else {
    $("#image_test").append(img);
    }
    });

So I m thinking that for some reason cocos2d-html5 has problems with CORS and jquery doesnt…

Hi Alex

It’s pretty normal, because you are using jQuery to load a image to dom. The thing is that WEBGL is more strict on cross domain security than dom. In the previous discussion, there is no problem to load the image itself, problem triggered when you want to draw this image with WEBGL api.

Huabin

Hi Huabin,

Thanks for the information, I didnt know that WebGL had a more strict cross-domain security.

To be more precise though, I didnt try to assign an image to a sprite, I tried to assign an image to UI, so doing something like this :

var panel = this.getWidgetByName("GemPackPanel").clone()
if ( item.url && item.url !== "" ){
  //CORS issue
  var tex = cc.TextureCache.getInstance().addImage(item.url);
  panel.getChildByName("ItemImage").loadTexture(tex);
}

And the error happens in cocos2d/core/textures/CCTextureCache.js in addImage() when cocos2d tries to :

image.src = path;

I looked for reference and I found this http://www.khronos.org/registry/webgl/specs/latest/1.0/
Section 4.2 is the one of interest to us now.

But looking at the code there https://github.com/cocos2d/cocos2d-html5/blob/develop/cocos2d/core/textures/CCTextureCache.js
addImage() is at l.398.

And it seems cross-origin image should work as the CORS request seems to be implemented…

So I am curious to know if anyone knows of an existing Cocos2d-html5 test that would test CORS request for using cross-domain images in ( Canvas and ) WebGL ?

It would be quite useful to have one, so anyone can quickly test if the server setup for CORS is just not done by their image/web provider, or if it s cocos2d that has an issue with it…

Thanks.

In fact all depends on the server you requested the image, if the server granted the authorization to your own server url, then this trick will work well image.crossOrigin = "Anonymous";. But if the server don’t allow any CORS access, then nothing in javascript can work throughout it.

On the server which you try to retrieve the images, you may set such parameters :
e.g. Access-Control-Allow-Origin: your server url

For more details on this topic: wikipeida

Huabin

I might be mistaken, but I think the facebook integration chapter of this book covers what you are trying to do:

I did a bit more invesdtigation on the topic and I found out that the server I was accessing resource from didnt have CORS headers in the response. So I had to use corsproxy to add them.

        var gameSceneNode = ccs.SceneReader.getInstance().createNodeWithSceneFile(Scene_MainScene);

        var size = cc.Director.getInstance().getWinSize();

        // CORS ERROR
        //var sprite = cc.Sprite.create("http://cdn.shephertz.com/repository/files/eb075343180ff254993d760eaeff219d9c6f3cd768c976f4cb7c25e6a6a7a88e/8e8984598d28645d304057d9a59cfd28e4648a60/ee227a6df135380c8bb1c4e9ad071c07e1fe284a.png");

        //WORKING
        var sprite = cc.Sprite.create("http://www.corsproxy.com/cdn.shephertz.com/repository/files/eb075343180ff254993d760eaeff219d9c6f3cd768c976f4cb7c25e6a6a7a88e/8e8984598d28645d304057d9a59cfd28e4648a60/ee227a6df135380c8bb1c4e9ad071c07e1fe284a.png");

        var spritelocal = cc.Sprite.create("Resources/Key_3.png");

        sprite.setPosition(cc.p(100,100));
        spritelocal.setPosition(cc.p(size.width-100,100));

        gameSceneNode.addChild(spritelocal,2);
        gameSceneNode.addChild(sprite,3);

        this.addChild(gameSceneNode);

Oh, great you found the solution!
I never heard about www.corsproxy.com, seem that it’s very useful to avoid CORS problems!

Hi,

I’m still stuck on that one.

If I use this:
var myUrl = “http://externalurl.com/image.png”;
var text = cc.TextureCache.getInstance().addImage(myUrl);

The path will be changed to:
http://mygame.com/res/http://externalurl.com/image.png
And obviously this won’t load anything.

How can I force the absolute url?

Thanks in advance!