CCTexture2D* Util::getGrayTexture(const char* filename){ typedef enum { RED = 0, GREEN = 1, BLUE = 2, ALPHA = 3 } PIXELS; CCImage *image = new CCImage(); image->initWithImageFile(filename); unsigned char* pixels = image->getData(); int len = image->getDataLen(); uint32_t *p = (uint32_t *)pixels; for(int i=0;i<len;i++){ uint8_t *rgbaPixel = (uint8_t *) &p[i]; //uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE]; uint32_t gray = 1.2*rgbaPixel[RED] + 1.0*rgbaPixel[GREEN] + 0.0*rgbaPixel[BLUE]; // set the pixels to gray rgbaPixel[RED] = gray; rgbaPixel[GREEN] = gray; rgbaPixel[BLUE] = gray; } CCTexture2D* texture = new CCTexture2D(); texture->autorelease(); texture->initWithImage(image); image->release(); return texture; }
// 주어진 파일로부터 RGBA를 가져온다. void HelloWorld::GetPaletteFromFile(char *filename, unsigned char *pPalette, int nNumColors) { CCImage *pImage = new CCImage(); CCTexture2D *pTex = new CCTexture2D(); pImage->initWithImageFile(filename, CCImage::kFmtPng); memcpy(pPalette, pImage->getData(), nNumColors * 4); // RGBA = 4 bytes }
bool EraserSprite::getEraserOk() { m_bEraserOk = false; CCImage* image = new CCImage(); image = m_pRTex->newCCImage(true); int m = 3; if (image->hasAlpha()) { m = 4; } unsigned char *data_= image->getData(); int x = 0, y = 0; /// 这里要一点,即Opengl下,其中心点坐标在左上角 for (x = 0; x < spriteSize.width; ++x) { for (y = 0 ; y < spriteSize.height; ++y) { unsigned char *pixel = data_ + (x + y * image->getWidth()) * m; // You can see/change pixels' RGBA value(0-255) here ! unsigned int r = (unsigned int)*pixel; unsigned int g = (unsigned int)*(pixel + 1); unsigned int b = (unsigned int)*(pixel + 2) ; unsigned int a = (unsigned int)*(pixel + 3); if (r != 0 && g != 0 && b != 0 && a != 0) { m_bEraserOk = false; break; } } if (spriteSize.height != y) { break; } } if (x == spriteSize.width && y == spriteSize.height) { m_bEraserOk = true; } delete image; return this->m_bEraserOk; }
bool FDPixelSprite::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) { if (this->isContainTouchLocation(pTouch) ) { ccColor4B c = {0, 0, 0, 0}; CCSize winSize = CCDirector::sharedDirector()->getWinSize(); CCPoint touchPoint = pTouch->getLocationInView(); CCSize cSize = this->getContentSize(); CCPoint point =this->getAnchorPointInPoints(); point = ccp(cSize.width - point.x,cSize.height- point.y); CCPoint pos(this->getPositionX() - point.x,winSize.height-this->getPositionY()- point.y); CCPoint localPoint = ccp(touchPoint.x - pos.x, touchPoint.y -pos.y); unsigned int x = localPoint.x, y = localPoint.y; //This method is currently only supports symmetric image //unsigned char *data_ = this->getTexture()->getFDImageData(); //Efficiency of this method is relatively low CCImage * img = new CCImage(); img->initWithImageFileThreadSafe(CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(TESTPNG) ); unsigned char *data_ = img->getData(); unsigned int *pixel = (unsigned int *)data_; pixel = pixel + (y * (int)this->getContentSize().width)* 1 + x * 1; c.r = *pixel & 0xff; c.g = (*pixel >> 8) & 0xff; c.b = (*pixel >> 16) & 0xff; c.a = (*pixel >> 24) & 0xff; if (c.a == 0) { CCLog("firedragonpzy:ccTouchBegan----------"); return false; }else { return true; } }
CCTexture2D* Util::getGrayTexture(CCTexture2D* texture){ typedef enum { RED = 0, GREEN = 1, BLUE = 2, ALPHA = 3 } PIXELS; CCSize textSize = texture->getContentSize(); CCSprite *temporarySprite = CCSprite::createWithTexture(texture); //就这么一小句搞了我半天了,不过能出来也值了 temporarySprite->setAnchorPoint(ccp(0,0)); CCRenderTexture *rt = CCRenderTexture::create(textSize.width, textSize.height); rt->begin(); temporarySprite->visit(); rt->end(); CCImage *image = rt->newCCImage(); unsigned char* pixels = image->getData(); int len = image->getDataLen(); uint32_t *p = (uint32_t *)pixels; for(int i=0;i<len;i++){ uint8_t *rgbaPixel = (uint8_t *) &p[i]; //uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE]; uint32_t gray = 1.2*rgbaPixel[RED] + 1.0*rgbaPixel[GREEN] + 0.0*rgbaPixel[BLUE]; // set the pixels to gray rgbaPixel[RED] = gray; rgbaPixel[GREEN] = gray; rgbaPixel[BLUE] = gray; } CCTexture2D* newtexture = new CCTexture2D(); newtexture->autorelease(); newtexture->initWithImage(image); image->release(); return newtexture; }
CCSprite * BSAddStrokeToLabel(cocos2d::CCLabelTTF * label, float size, cocos2d::ccColor3B color, GLubyte opacity) { CCPoint originalPos = label->getPosition(); ccColor3B originalColor = label->getColor(); GLubyte originalOpacity = label->getOpacity(); bool originalVisibility = label->isVisible(); ccBlendFunc originalBlend = label->getBlendFunc(); label->setColor(color); label->setOpacity(opacity); ccBlendFunc bf = {GL_SRC_ALPHA, GL_ONE}; label->setBlendFunc(bf); CCPoint bottomLeft = ccp(label->getTexture()->getContentSize().width * label->getAnchorPoint().x + size, label->getTexture()->getContentSize().height * label->getAnchorPoint().y + size); CCRenderTexture* rt = CCRenderTexture::create(label->getTexture()->getContentSize().width + size * 2, label->getTexture()->getContentSize().height + size * 2); /* 在原始位置绘制文字,用于镂空用 */ label->setPosition(bottomLeft); rt->begin(); label->visit(); rt->end(); CCImage * originText = rt->newCCImage(); glBlendEquation(GL_BLEND_EQUATION_ALPHA); /* 在各个方向上移动文字,重叠得到未镂空的描边 */ rt->begin(); /* Bresenham's circle algorithm */ int radis = 3 * size; for (int x = 0, y = radis, d = 3 - 2 * radis; x <= y; ++x) { float xx = x / 3.0F, yy = y / 3.0F; label->setPosition(ccp(bottomLeft.x + xx, bottomLeft.y + yy)); label->visit(); label->setPosition(ccp(bottomLeft.x - xx, bottomLeft.y + yy)); label->visit(); label->setPosition(ccp(bottomLeft.x + xx, bottomLeft.y - yy)); label->visit(); label->setPosition(ccp(bottomLeft.x - xx, bottomLeft.y - yy)); label->visit(); label->setPosition(ccp(bottomLeft.x + yy, bottomLeft.y + xx)); label->visit(); label->setPosition(ccp(bottomLeft.x - yy, bottomLeft.y + xx)); label->visit(); label->setPosition(ccp(bottomLeft.x + yy, bottomLeft.y - xx)); label->visit(); label->setPosition(ccp(bottomLeft.x - yy, bottomLeft.y - xx)); label->visit(); if (d < 0) { d = d + 4 * x + 6; } else { d = d + 4 * (x - y) + 10; y --; } } rt->end(); /* TODO: ugly workaround. rendertexture多次绘制颜色叠加,需要取色值大的那个,需要通过glBlendEquation(GL_MAX)实现。 * see http://stackoverflow.com/questions/2143690/is-it-possible-to-achieve-maxas-ad-opengl-blending */ CCImage * strokedText = rt->newCCImage(); unsigned char * pStorke = strokedText->getData(); unsigned char * pErase = originText->getData(); for (int i = 0; i < strokedText->getDataLen(); ++i) { if ((unsigned int) pErase[i * 4] != 0) { *(unsigned int *) &pStorke[i * 4] = 0; } else if ((unsigned int) pStorke[i * 4] != 0) { unsigned char * pixel = &pStorke[i * 4]; (*pixel++) = color.r; (*pixel++) = color.g; (*pixel++) = color.b; *pixel = opacity; } } originText->release(); /* 用RenderTexture构造一个Sprite,以实现支持透明度 FadeIn FadeOut */ CCTexture2D * texture2D = new CCTexture2D(); texture2D->initWithImage(strokedText); strokedText->release(); CCSprite * sprite = CCSprite::createWithTexture(texture2D); texture2D->release(); label->setPosition(originalPos); label->setColor(originalColor); label->setBlendFunc(originalBlend); label->setVisible(originalVisibility); label->setOpacity(originalOpacity); sprite->setPosition(ccp(label->getTexture()->getContentSize().width / 2, label->getTexture()->getContentSize().height / 2)); label->addChild(sprite, -1); return sprite; }
void* downloadToSave(void* ppCurl) { tileData* pData = (tileData*)ppCurl; pData->nTryTime--; pData->pRawTile; CCString strUrl = pData->pMaker->getMapStrategy()->getUrl(pData->pRawTile->x,pData->pRawTile->y,pData->pRawTile->z); std::string strResponse; CURLcode res; CURL* curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_URL, strUrl.getCString()); curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteImageData); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); res = curl_easy_perform(curl); int retcode = 0; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE , &retcode); double length; res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD , &length); if (res==CURLE_OK && retcode == 200 && ((int)length)>0 && strResponse.size()>0) { CCImage* pImage = new CCImage; if(pImage->initWithImageData((void*)strResponse.c_str(),(int)length) == false) { delete pImage; pImage = NULL; curl_easy_cleanup(curl); if(pData->nTryTime>0) { pData->nTryTime--; pthread_t pid; pthread_create(&pid, NULL, downloadToSave, (void*)pData); } else { pthread_mutex_lock(&cachemutex); pData->pMaker->update(pData->pRawTile); pthread_mutex_unlock(&cachemutex ); delete pData; pData = NULL; } } else { pthread_mutex_lock(&cachemutex); pData->pMaker->update(NULL); pthread_mutex_unlock(&cachemutex ); curl_easy_cleanup(curl); ////////////////////////////////////////////////////////////////////////// CCString strPath; std::string strRootPath = pData->pMaker->getSavePath(); strPath.initWithFormat("%s//%d//%d//",strRootPath.c_str(), pData->pRawTile->z,pData->pRawTile->y); if (!SunFile::IsExist(strPath.getCString(),true)) { SunFile::MkDirEx(strPath.getCString()); } CCString strFile; strFile.initWithFormat("%s%d.%s",strPath.getCString(), pData->pRawTile->x, pData->pMaker->getImageType()); if (!SunFile::IsExist(strFile.getCString(),false)) { std::string strName = pData->pMaker->getImageType(); if ( strName.compare("tiff")== 0) { unsigned char* m_pData = pImage->getData(); int m_nWidth,m_nHeight; m_nWidth = m_nHeight = 256; unsigned char *pTempData = new unsigned char[m_nWidth * m_nHeight * 3]; for (int i = 0; i < m_nHeight; ++i) { for (int j = 0; j < m_nWidth; ++j) { pTempData[(i * m_nWidth + j) * 3] = m_pData[(i * m_nWidth + j) * 4]; pTempData[(i * m_nWidth + j) * 3 + 1] = m_pData[(i * m_nWidth + j) * 4 + 1]; pTempData[(i * m_nWidth + j) * 3 + 2] = m_pData[(i * m_nWidth + j) * 4 + 2]; } } save_tiff_rgb(strFile.getCString(),256,256,(const char*)pTempData); delete pTempData; } else { pImage->saveToFile(strFile.getCString()); } } delete pData; pData = NULL; } delete pImage; pImage = NULL; } else { curl_easy_cleanup(curl); if(pData->nTryTime>0) { pData->nTryTime--; pthread_t pid; pthread_create(&pid, NULL, downloadToSave, (void*)pData); } else { pthread_mutex_lock(&cachemutex); pData->pMaker->update(pData->pRawTile); pthread_mutex_unlock(&cachemutex ); delete pData; pData = NULL; } } return NULL; }
CCSprite* CCColorUtil::graylightWithCCSprite(CCSprite* oldSprite,bool isLight) { //CCSprite转成CCimage CCPoint ptOldAnchor = oldSprite->getAnchorPoint(); CCPoint ptOld = oldSprite->getPosition(); oldSprite->setAnchorPoint(ccp(0,0)); oldSprite->setPosition(ccp(0,0)); CCRenderTexture *outTexture = CCRenderTexture::create((int)oldSprite->getContentSize().width*1,(int)oldSprite->getContentSize().height*1); outTexture->begin(); oldSprite->visit(); outTexture->end(); oldSprite->setAnchorPoint(ptOldAnchor); oldSprite->setPosition(ptOld); CCImage* finalImage = outTexture->newCCImage(); unsigned char *pData = finalImage->getData(); int iIndex = 0; if(isLight) { for (int i = 0; i < finalImage->getHeight(); i ++) { for (int j = 0; j < finalImage->getWidth(); j ++) { // highlight int iHightlightPlus = 50; int iBPos = iIndex; unsigned int iB = pData[iIndex]; iIndex ++; unsigned int iG = pData[iIndex]; iIndex ++; unsigned int iR = pData[iIndex]; iIndex ++; //unsigned int o = pData[iIndex]; iIndex ++; //原来的示例缺少 iB = (iB + iHightlightPlus > 255 ? 255 : iB + iHightlightPlus); iG = (iG + iHightlightPlus > 255 ? 255 : iG + iHightlightPlus); iR = (iR + iHightlightPlus > 255 ? 255 : iR + iHightlightPlus); // iR = (iR < 0 ? 0 : iR); // iG = (iG < 0 ? 0 : iG); // iB = (iB < 0 ? 0 : iB); pData[iBPos] = (unsigned char)iB; pData[iBPos + 1] = (unsigned char)iG; pData[iBPos + 2] = (unsigned char)iR; } } }else{ for (int i = 0; i < finalImage->getHeight(); i ++) { for (int j = 0; j < finalImage->getWidth(); j ++) { // gray int iBPos = iIndex; unsigned int iB = pData[iIndex]; iIndex ++; unsigned int iG = pData[iIndex]; iIndex ++; unsigned int iR = pData[iIndex]; iIndex ++; //unsigned int o = pData[iIndex]; iIndex ++; //原来的示例缺少 unsigned int iGray = 0.3 * iR + 0.4 * iG + 0.2 * iB; pData[iBPos] = pData[iBPos + 1] = pData[iBPos + 2] = (unsigned char)iGray; } } } CCTexture2D *texture = new CCTexture2D; texture->initWithImage(finalImage); CCSprite* newSprite = CCSprite::createWithTexture(texture); delete finalImage; texture->release(); return newSprite; }
CCRect GameUtil::getFitRect(CCSprite* pSprite) { // 원본의 원래위치 백업 CCPoint ptOrg = pSprite->getPosition(); // 원본 스프라이트 위치를 Center로 설정 pSprite->setPosition(ccp(pSprite->getContentSize().width/2, pSprite->getContentSize().height/2)); // CCImage를 만들기 위해서 RenderTexture 생성 CCRenderTexture * rtNew = CCRenderTexture::create((int)pSprite->getContentSize().width, (int)pSprite->getContentSize().height); rtNew->begin(); pSprite->visit(); rtNew->end(); // CCImage 생성 CCImage *pImage = rtNew->newCCImage(); int width = pImage->getWidth(); int height = pImage->getHeight(); int bytesPerComponent = pImage->getBitsPerComponent() / 8; // 기본값 8bit bool bAlpha = pImage->hasAlpha(); int nRGBA = 4; if (!bAlpha) nRGBA = 3; // 픽셀 데이터 (RGBA 순서, 각각 bytesPerComponent 크기만큼) unsigned char* pData = pImage->getData(); int index = 0; int l=5000; // left int r=0; // right int t=5000; // top int b=0; // bottom unsigned char* ptr; for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { index = (y*width + x) * bytesPerComponent * nRGBA; ptr = pData + index; if (0 != ptr[0] || 0 != ptr[1] || 0 != ptr[2]) { l = min(l, x); // left r = max(r, x); // right t = min(t, y); // top b = max(b, y); // bottpm } } } // 좌표계 보정 (픽셀데이터는 좌상단을 0,0 으로 하기때문에) int b2 = pSprite->getContentSize().height - t; int t2 = pSprite->getContentSize().height - b; CC_SAFE_DELETE(pImage); // 원래 위치로 설정 pSprite->setPosition(ptOrg); CCRect rc; rc.origin.x = l; rc.origin.y = t2; rc.size.width = r - l; rc.size.height = b2 - t2; return rc; }
CCSprite* GameUtil::fitSprite(CCSprite* pSprite) { // 원본의 원래위치 백업 CCPoint ptOrg = pSprite->getPosition(); // 원본 스프라이트 위치를 Center로 설정 pSprite->setPosition(ccp(pSprite->getContentSize().width/2, pSprite->getContentSize().height/2)); // CCImage를 만들기 위해서 RenderTexture 생성 CCRenderTexture * rtNew = CCRenderTexture::create((int)pSprite->getContentSize().width, (int)pSprite->getContentSize().height); rtNew->begin(); pSprite->visit(); rtNew->end(); // CCImage 생성 CCImage *pImage = rtNew->newCCImage(); int width = pImage->getWidth(); int height = pImage->getHeight(); int bytesPerComponent = pImage->getBitsPerComponent() / 8; // 기본값 8bit bool bAlpha = pImage->hasAlpha(); int nRGBA = 4; if (!bAlpha) nRGBA = 3; // 픽셀 데이터 (RGBA 순서, 각각 bytesPerComponent 크기만큼) unsigned char* pData = pImage->getData(); int index = 0; int l=5000; // left int r=0; // right int t=0; // top int b=5000; // bottom unsigned char* ptr; for (int x=0; x<width; x++) { for (int y=0; y<height; y++) { index = (y*width + x) * bytesPerComponent * nRGBA; ptr = pData + index; if (0 != ptr[0] || 0 != ptr[1] || 0 != ptr[2]) { l = min(l, x); // left r = max(r, x); // right t = max(t, y); // top b = min(b, y); // bottom } } } // 좌표계 보정 (픽셀데이터는 좌상단을 0,0 으로 하기때문에) int b2 = pSprite->getContentSize().height - t; int t2 = pSprite->getContentSize().height - b; CC_SAFE_DELETE(pImage); // 원래 위치로 설정 pSprite->setPosition(ptOrg); // 스프라이트로 생성 CCSprite* pCrop = CCSprite::createWithTexture(pSprite->getTexture()); pCrop->setTextureRect(CCRect(l, b2, r-l, t2-b2)); pCrop->setPosition(ccp(pCrop->getContentSize().width/2, pCrop->getContentSize().height/2)); pCrop->setFlipY(true); // 크기에 꼭 맞는 새로운 RenderTexture를 만든다. CCRenderTexture * rtNew2 = CCRenderTexture::create(r-l, t2-b2); rtNew2->begin(); pCrop->visit(); rtNew2->end(); // 크기에 꼭 맞는 새로운 Sprite를 만든다. CCSprite *retSprite = CCSprite::createWithTexture(rtNew2->getSprite()->getTexture()); retSprite->setFlipY(true); rtNew2->release(); pCrop->release(); return retSprite; }
static void* loadImage(void* data) { AsyncStruct *pAsyncStruct = NULL; while (true) { // create autorelease pool for iOS CCThread thread; thread.createAutoreleasePool(); // wait for rendering thread to ask for loading if s_pAsyncStructQueue is empty int semWaitRet = sem_wait(s_pSem); if( semWaitRet < 0 ) { CCLOG( "CCTextureCache async thread semaphore error: %s\n", strerror( errno ) ); break; } std::queue<AsyncStruct*>* pQueue = s_pAsyncStructQueue; pthread_mutex_lock(&s_asyncStructQueueMutex);// get async struct from queue if (pQueue->empty()) { pthread_mutex_unlock(&s_asyncStructQueueMutex); if (need_quit) break; else continue; } else { pAsyncStruct = pQueue->front(); pQueue->pop(); pthread_mutex_unlock(&s_asyncStructQueueMutex); } const char* filename = pAsyncStruct->filename.c_str(); // compute image type CCImage::EImageFormat imageType = CCImage::computeImageFormatType(pAsyncStruct->filename); if (imageType == CCImage::kFmtUnKnown) { CCLOG("unsupported format %s",filename); delete pAsyncStruct; continue; } // generate image CCImage* pImage = pAsyncStruct->image; if (pImage && !pImage->initWithImageFileThreadSafe(filename, imageType)) { pAsyncStruct->image = NULL; CC_SAFE_RELEASE(pImage); CCLOG("can not load %s", filename); continue; } unsigned char* tempData = CCImage::convertToRequiredFormat(pImage); if (tempData != pImage->getData()) { CCSize size = CCSizeMake(pImage->getWidth(), pImage->getHeight()); size_t bpp = pImage->getBitsPerComponent(); CCTexture2DPixelFormat pixelFormat = pImage->hasAlpha() ? CCTexture2D::getDefaultAlphaPixelFormat() : (bpp >= 8 ? kCCTexture2DPixelFormat_RGB888 : kCCTexture2DPixelFormat_RGB565); pAsyncStruct->image = NULL; CC_SAFE_RELEASE(pImage); pAsyncStruct->data = tempData; pAsyncStruct->size = size; pAsyncStruct->pixelFormat = pixelFormat; } // generate image info ImageInfo* pImageInfo = new ImageInfo(); pImageInfo->asyncStruct = pAsyncStruct; pImageInfo->imageType = imageType; // put the image info into the queue pthread_mutex_lock(&s_ImageInfoMutex); s_pImageQueue->push(pImageInfo); pthread_mutex_unlock(&s_ImageInfoMutex); } if( s_pSem != NULL ) { #if CC_ASYNC_TEXTURE_CACHE_USE_NAMED_SEMAPHORE sem_unlink(CC_ASYNC_TEXTURE_CACHE_SEMAPHORE); sem_close(s_pSem); #else sem_destroy(s_pSem); #endif s_pSem = NULL; delete s_pAsyncStructQueue; delete s_pImageQueue; } return 0; }