renderTexture->saveToFile() bugged for image alpha values


#1

Take any image that has transparent pixels in it and try to save it as a png using renderTexture. The transparent pixels will get added with the background color of the renderTexture despite setting the background’s alpha channel to zero with clear(0,0,0,0). Below is the code I used:

auto sprite = Sprite::create("original.png");
auto renderTexture = RenderTexture::create(64, 64, Texture2D::PixelFormat::RGBA8888);
renderTexture->clear(0,0,0,0);
renderTexture->begin();
sprite->setAnchorPoint(Vec2(0, 0));
sprite->setPosition(Vec2(0,0));
sprite->visit();
renderTexture->end();
renderTexture->saveToFile("rendertexture.png", Image::Format::PNG);

So in the above case because I cleared with rgba(0,0,0,0), my transparent pixels will end up being darker. One would assume that having an alpha of zero shouldn’t change the image at all.

Here is an example of the effect. The first image is my original, a square with the light green color rbga(55,255,0,100). The second image is the renderTexture image I get after running the above code. You can see it is now a dark green color rgba(21,100,0,100).

Original:
original
RenderTexture:
rendertexture

This error was also reproduced by @KAMIKAZE so I have opened a github issue here:
https://github.com/cocos2d/cocos2d-x/issues/18193


#2


@zhangxm Are you here? Active on forum?


#3

No updates?


#4

@zhangxm any news? A lot of time passed but this issue hasn’t’ been fixed.
https://github.com/cocos2d/cocos2d-x/issues/18193

Post by 26 September:

@hotcoco maybe you found how to fix this?


#5

@zhangxm
Just want to assume this bug and add something.

For image:
1

Use code:

auto sprite = Sprite::create("1.png");
sprite->setPosition(Vec2(visibleSize.width * 0.5, visibleSize.height * 0.5));
addChild(sprite);
    
auto render = RenderTexture::create(visibleSize.width, visibleSize.height);
render->begin();
visit();
render->end();
render->saveToFile("rendered.png");

I have this scene:

sceme

Result rendered image of this scene:

rendered

Take a closer look:

Notice that not only transparent image but text has some artefacts.

Even more:

Add this code on top of code posted before:

auto gradient = LayerGradient::create(Color4B(100, 250, 100, 255.0), Color4B(5, 5, 5, 0.0));
gradient->setContentSize(visibleSize);
addChild(gradient);

Result of rendered image compare to actual scene with gradient:

Left - rendered. Right - actual scene.

Notice - rendered gradient is different than actual saved file.

It’s like has some transparency where it should’t have. Top of gradient isn’t transparent, but on rendered image - it’s transparent:

screen shot