利用CCHttpRequest获取网上http地址的图片并缓存到本地生成CCSprite用于显示
//图片结构
class imgstruct : public CCObject { public: imgstruct(const char* iName, const char* idStr, CCLayer* _layer, bool mask) { imageName = string(iName); observerId = string(idStr); layer = _layer; useMask = mask; } ~imgstruct() { } string imageName; string observerId; CCLayer* layer; //父layer bool useMask; };
//图片监听,下载完成触发 class CCImageNotificationCenter : public CCNotificationCenter { public: DECLARE_SINGLETON_CLASS(CCImageNotificationCenter); CCImageNotificationCenter(); ~CCImageNotificationCenter(); CCString addObserver(const char *imageName,CCLayer* layer,bool useMask); void imageLoaded(); void removeObserver(const char *name); void postNotification(const char *name, CCObject *object); void imageLoaded(CCObject *obj); static CCSprite* getSpriteFromWriteablePath(const char* name); private: CCNotificationCenter m_notificationCenter; int m_observerID; };
具体实现
CCString CCImageNotificationCenter::addObserver(const char *imageName, CCLayer* layer, bool useMask) { CCString* observerIDstr = CCString::createWithFormat("%d",m_observerID); m_notificationCenter.addObserver(this, callfuncO_selector(CCImageNotificationCenter::imageLoaded), observerIDstr->getCString(), new imgstruct(imageName, observerIDstr->getCString(), layer, useMask)); m_observerID++; return observerIDstr->getCString(); } void CCImageNotificationCenter::removeObserver(const char *name) { m_notificationCenter.removeObserver(this, name); } void CCImageNotificationCenter::postNotification(const char *name, CCObject *object) { m_notificationCenter.postNotification(name, object); } void CCImageNotificationCenter::imageLoaded(CCObject *obj) { imgstruct* img = (imgstruct*)obj; CCLOG("imageLoaded success,imageName:%s",img->imageName.c_str()); CCSprite* sprite = CCImageNotificationCenter::getSpriteFromWriteablePath(img->imageName.c_str()); CCLOG("got sprite 0x%X", sprite); if (img->useMask) { img->layer->addChild(CCImageNotificationCenter::createMaskedSprite(sprite,"mask.png")); } else { float scale_ = (float) img->layer->getContentSize().width / (float)sprite->getContentSize().width; sprite->setAnchorPoint(ccp(0,0)); sprite->setScale( scale_ ); img->layer->addChild(sprite); } this->removeObserver(img->observerId.c_str()); img->release(); } CCSprite* CCImageNotificationCenter::getSpriteFromWriteablePath(const char* name) { std::string path = CCFileUtils::sharedFileUtils()->getWriteablePath(); path += name; FILE* fp = fopen(path.c_str(),"rb"); if (!fp) { return NULL; } fseek(fp,0,SEEK_END); int len = ftell(fp); fseek(fp,0,SEEK_SET); char* buf = (char*)malloc(len); fread(buf,len,1,fp); fclose(fp); CCImage* img = new CCImage; img->initWithImageData(buf,len); free(buf); cocos2d::CCTexture2D* texture = new cocos2d::CCTexture2D(); bool isImg = texture->initWithImage(img); img->release(); if (!isImg) { delete texture; return CCSprite::create("default.png");//加载资源并非图片时返回的默认图 } CCSprite* sprite = CCSprite::createWithTexture(texture); texture->release(); return sprite; }
实现ImageDownload类
class ImageDownloader : public cocos2d::CCObject { DECLARE_SINGLETON_CLASS(ImageDownloader); public: ImageDownloader(); ~ImageDownloader(); void CreateLuaFunc(); void SendHttpRequest(const char* url, CCLayer* layer, const char* filename); void HttpRequestComplete(CCHttpClient *sender, CCHttpResponse *response); CCString observerID; CCLayer* container; bool useMask; };
void ImageDownloader::SendHttpRequest(const char* url, CCLayer* layer, const char* filename) { CCHttpRequest* request = new CCHttpRequest(); this->container = layer; if (this->container) { CCImageNotificationCenter::CreateInstance(); this->observerID = CCImageNotificationCenter::GetInstance()->addObserver(filename,container,useMask); } request->setUrl(url); // request->setUrl("http://neoimaging.beareyes.com.cn/png2/ni_png_2_1518.png"); request->setRequestType(CCHttpRequest::kHttpGet); request->setResponseCallback(this, httpresponse_selector(ImageDownloader::HttpRequestComplete)); request->setTag("GET IMAGE"); CCHttpClient::getInstance()->send(request); request->release(); } void ImageDownloader::HttpRequestComplete(CCHttpClient *sender, CCHttpResponse *response) { if (!response) { return; } // You can get original request type from: response->request->reqType if (0 != strlen(response->getHttpRequest()->getTag())) { CCLog("%s completed", response->getHttpRequest()->getTag()); } int statusCode = response->getResponseCode(); char statusString[64] = {}; sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag()); CCLog("response code: %d", statusCode); if (!response->isSucceed()) { CCLog("response failed"); CCLog("error buffer: %s", response->getErrorBuffer()); return; } // dump data std::vector<char> *buffer = response->getResponseData(); std::string path = CCFileUtils::sharedFileUtils()->getWriteablePath(); std::string bufffff(buffer->begin(),buffer->end()); //保存到本地文件 path += "dl.png"; CCLOG("path: %s",path.c_str()); FILE *fp = fopen(path.c_str(), "wb+"); fwrite(bufffff.c_str(), 1,buffer->size(), fp); fclose(fp); //传入container的下载请求会添加侦听,待下载完毕自动添加到container上 if (this->container) { // container 是一个CCLayer ,用来显示动态加载的资源 CCImageNotificationCenter::GetInstance()->cocos2d::CCNotificationCenter::postNotification(this->observerID.getCString()); } }