[RESOLVED] Loading a CCSprite from a URL

Hi,

I would like to load a CCSprite from a given URL but I did not get success… Has someone had success loading a sprite from a URL? Has anyone an example of how I could load it?

Thank you

It seems that someone has in this thread: http://www.cocos2d-x.org/boards/6/topics/12507

This post also has a link to some code that does what you want : http://www.cocos2d-x.org/boards/18/topics/21963

The demo worked out of the box and was easy to modify.

Thank you all!

Now I get the CCSprite from URL but the game is freezed while the image is loaded from the URL.

Does anyone know how can I get the image in a other thread or if there is a way to get the image in background and show it when it is loaded?

You can use pthread for that: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_use_pthread Also I think that there was some example in test project.

Thank you Leszek X, step by step I am going getting what I want… :slight_smile:

Now, the image is loaded in a different thread, but when it appears in the layer, it is all black… I have read that this could be due of OpenGL (you can not access to OpenGL in a thread).

Does anyone solved this problem in some way?

Thank you!

You should use another thread only to download the image and save it somewhere and not to create a sprite from it. The sprite must be create in main thread. So in another thread you could for example just change some bool flag that will indicate that image is downloaded and saved somewhere and in main thread check this flag and when it is downloaded then you can create the sprite in main thread.

Thank you again, Leszek X!

I just have the sprite loaded in background!

Thanks for your help

Emilio Exposito

What’t mean “loaded in backgroud”?

  1. save file in sub thread
  2. load image in main thread

Emilio Exposito wrote:

Thank you again, Leszek X!
>
I just have the sprite loaded in background!
>
Thanks for your help

Could you share your code? I think many people will like this. Thanks in advance!

Ok, I will upload the code in a couple of days (as soon as I get to my office).

If along the next week I do not share the methods, please, send me a message.

Emilio Exposito wrote:

Ok, I will upload the code in a couple of days (as soon as I get to my office).
>
If along the next week I do not share the methods, please, send me a message.

Hi Emilio Exposito,
Please share your methods if you are not busy.
I’m looking forward to hearing from you.
Thanks.

Emilio Exposito wrote:

Ok, I will upload the code in a couple of days (as soon as I get to my office).
>
If along the next week I do not share the methods, please, send me a message.

About two weeks pass and i have been waiting your answer…

Hello, sorry for the delay but my actual work is very stressful… anyways, here is the steps to get the CCSprite from a URL (if anyone has other method or detect any problem with my code, please tell us something):

First of all I have defined two structures:
// This one is to handle the data writing in the disk.
struct MemoryStruct {
char* memory;
size_t size;
size_t writepos;
};
//This one is to handle which image is loaded (in my game I launch three or four threads and I need to know which image is loaded)
struct DataStruct {
const char* URL;
const char* name;
};

//It saves in memory the image
size_t WriteMemoryCallback(void contents, size_t size, size_t nmemb, voiduserp) {
struct MemoryStruct mem = userp;
size_t realsize = size
nmemb;
mem~~>memory = realloc;
if {
// out of memory!
CCLog");
return 0;
}
memcpy, contents, realsize);
mem~~>size += realsize;
mem~~>memory[mem~~>size] = 0;
return realsize;
}

//This is the method to call the URL
// Worker thread
void* networkThread(void data) {
CURL
curl_handle;
const char* name = ((struct DataStruct**)data)>name;
const char* URL = data)
>URL;
struct MemoryStruct chunk;
chunk.memory = malloc; /** will be grown as needed by the realloc above /
chunk.size = 0; /
no data at this point /
curl_global_init;
/
init the curl session /
curl_handle = curl_easy_init;
/
specify URL to get /
curl_easy_setopt;
/
follow the redirection, if there is*/
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, true);
/* Fixed the timeout error /
curl_easy_setopt;
/
send the loaded data to this function /
curl_easy_setopt;
/
we pass our ‘chunk’ struct to the callback function /
curl_easy_setopt&chunk);
/
some servers don’t like requests that are made without a user-agent field, so we provide one /
curl_easy_setopt;
/
get it! /
curl_easy_perform;
/
cleanup curl stuff /
curl_easy_cleanup;
/

* Now, our chunk.memory points to a memory block that is chunk.size
* bytes big and contains the remote file.
*/
std::string dir = "The path in disk where you want to write the image, in my case CCFileUtils::sharedFileUtils()>getWritablePath;"
dir.append; //The name of the image
remove); //If the file already exists, it is deleted if you need it
FILE file = fopen, “wb+”);
if {
fwrite, chunk.size, file);
fclose;
//Here you should indicates to the main thread that the image is loaded already
}
/
You should be aware of the fact that at this point we might have an
* allocated data block, and nothing has yet deallocated that data. So when
* you’re done with it, you should free it as a nice application.
/
CCLOG ("%lu bytes retrieved\n", (long)chunk.size); //Just to know the bytes retrieved
if {
free;
}
/
we’re done with libcurl, so clean it up /
curl_global_cleanup;
free;
pthread_exit;
return 0;
}
The code to launch all the process is:
DataStruct
data = malloc);
data
>name = imageName; //The name of the file
data->URL = URL; //The URL where the image is
pthread_create(&s_imageThread, NULL, networkThread, (void *)data); //Launch the process

I hope this code will be useful for you, and any doubt, please do not hesitate to ask me anything. Again, sorry for the delay… :frowning:

Emilio Exposito wrote:

Hello, sorry for the delay but my actual work is very stressful… anyways, here is the steps to get the CCSprite from a URL (if anyone has other method or detect any problem with my code, please tell us something):

Yeah, thanks for your sharing!

Hi Emilio Exposito,
Your code work perfectly. I wish i can made some improvements base on your code but because of my bad C++ skill, it’s not work :frowning:

  1. I want to make a class download image to reuse in other projects, it should have: input is image’s URL, image name. Call back before download, finish download.

  2. Can work for many image at the same time.

If you have free time, i hope you can make it for me and community :smiley:
Thanks in advance!