RenderTexture Save and Load file doesn't work on Android

Hi,

I am using RenderTexture to save and load image, it works well ọn iOS but not on Android.

Here is my sample code:

// Create render texture and capture image from spriteA
RenderTexture *render = RenderTexture::create(100,100);
render->begin();
spriteA->visit();
render->end();

//Save image file from Render Texture
render->saveToFile(“SavedFileName”, Image::Format::PNG)

//Load file into Sprite then
std::string fullpath = FileUtils::getInstance()->getWritablePath() + “SavedFileName”;
Sprite *sprite = Sprite::create(fullpath);

The sprite with image the same as spriteA above but it’s quite empty on Android.

Anybody help?

Thank you.

Do you really need save render to image? You can use render->getSprite() to load sprite.
Also, by default saveToFile set bool isRGBA to true, try set it to false like this render->saveToFile("SavedFileName", Image::Format::PNG, false) if it not help try Image::Format::JPG.

Thank you for your feedback.

I need to save file and use it in other place. It works well on iOS but not on Android. By the way, I don’t know what location that the file is stored in Android.

Could you help me to make it works on Android? Thank you.

Ok, i tested you code example. I think i know what you problem. saveToFile need time, so you need check if render finish saving file. Better use callback for this, for example lambda

render->saveToFile("SavedFileName", Image::Format::PNG, true, [] (RenderTexture* texture, const std::string& string) {
 //save file finished
 //some code here
} );

or CC_CALLBACK

render->saveToFile("image.png", Image::Format::PNG, true, CC_CALLBACK_2(YourClass::saveToFileCallback, target));

//somewhere else in your code

YourClass::saveToFileCallback(RenderTexture* texture, const std::string& string)
{
 //save file finished
 //some code here
}

you can create new sprite fom image inside callback or call method that creates sprite.

Tested on Samsung Galaxy Note 3 Android 5.0

1 Like

Thanks you very much ! It works fine !

Here is my example !

auto drawSprite = this->getChildByName("drawSprite "); // this is a sprite , I added this in my code . auto drawSprite = Sprite::create("...") ..v..v.. 

Size pixelSize = Director::getInstance()->getWinSizeInPixels();

auto renderTexture = RenderTexture::create(drawSprite->getBoundingBox().size.width, drawSprite->getBoundingBox().size.height);
renderTexture->retain();
renderTexture->setKeepMatrix(true);
renderTexture->setVirtualViewport(Vec2(162,768-473), Rect(0, 0, 1136,768), Rect(0, 0, pixelSize.width, pixelSize.height));
renderTexture->beginWithClear(0, 0, 0, 0);
drawSprite->visit();
renderTexture->end();

std::string fileName = "avatar.png";

renderTexture->saveToFile(fileName, Image::Format::PNG, true, CC_CALLBACK_2(HelloWorld::saveToFileCallback, this));
//Add this function to avoid crash if we switch to a new scene.
    //On android , I added this line to fix crash at Layer::OnDraw function        
Director::getInstance()->getRenderer()->render();
...........................................................................
...........................................................................
void HelloWorld::saveToFileCallback(cocos2d::RenderTexture * renderTexture, const 
std::string & pathFile)
{
if (m_sprite&& !pathFile.empty())
{
	TextureCache::getInstance()->removeTexture(m_sprite->getTexture());
	m_sprite->setSpriteFrame(Sprite::create(pathFile)->getSpriteFrame());
	m_sprite->setScale(0.555555556f);
	renderTexture->setKeepMatrix(false);
}
}