智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...

导航

cocos2d-x CCHttpRequest获取网络图片并显示

Posted on 2014-10-30 15:14  Bill Yuan  阅读(4689)  评论(0编辑  收藏  举报

转自:http://www.cnblogs.com/hzj730/p/3178431.html

//图片结构
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());
    }
}