mirror of https://github.com/axmolengine/axmol.git
Merge pull request #5365 from natural-law/issue3964
closed #3964: Solve the bug of Image::saveImageToPNG().
This commit is contained in:
commit
19205e3db8
|
@ -446,10 +446,23 @@ Image* RenderTexture::newImage(bool fliimage)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->begin();
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, _FBO);
|
||||||
|
|
||||||
|
//TODO move this to configration, so we don't check it every time
|
||||||
|
/* Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
|
||||||
|
*/
|
||||||
|
if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
|
||||||
|
{
|
||||||
|
// -- bind a temporary texture so we can clear the render buffer without losing our texture
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0);
|
||||||
|
CHECK_GL_ERROR_DEBUG();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
|
||||||
|
}
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(0,0,savedBufferWidth, savedBufferHeight,GL_RGBA,GL_UNSIGNED_BYTE, tempData);
|
glReadPixels(0,0,savedBufferWidth, savedBufferHeight,GL_RGBA,GL_UNSIGNED_BYTE, tempData);
|
||||||
this->end();
|
glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);
|
||||||
|
|
||||||
if ( fliimage ) // -- flip is only required when saving image to file
|
if ( fliimage ) // -- flip is only required when saving image to file
|
||||||
{
|
{
|
||||||
|
|
|
@ -948,7 +948,7 @@ bool Image::initWithPngData(const unsigned char * data, ssize_t dataLen)
|
||||||
}
|
}
|
||||||
png_read_image(png_ptr, row_pointers);
|
png_read_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
png_read_end(png_ptr, NULL);
|
png_read_end(png_ptr, nullptr);
|
||||||
|
|
||||||
_preMulti = false;
|
_preMulti = false;
|
||||||
|
|
||||||
|
@ -1094,7 +1094,7 @@ bool Image::initWithTiffData(const unsigned char * data, ssize_t dataLen)
|
||||||
tiffMapProc,
|
tiffMapProc,
|
||||||
tiffUnmapProc);
|
tiffUnmapProc);
|
||||||
|
|
||||||
CC_BREAK_IF(NULL == tif);
|
CC_BREAK_IF(nullptr == tif);
|
||||||
|
|
||||||
uint32 w = 0, h = 0;
|
uint32 w = 0, h = 0;
|
||||||
uint16 bitsPerSample = 0, samplePerPixel = 0, planarConfig = 0;
|
uint16 bitsPerSample = 0, samplePerPixel = 0, planarConfig = 0;
|
||||||
|
@ -1116,7 +1116,7 @@ bool Image::initWithTiffData(const unsigned char * data, ssize_t dataLen)
|
||||||
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
_data = static_cast<unsigned char*>(malloc(_dataLen * sizeof(unsigned char)));
|
||||||
|
|
||||||
uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
uint32* raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
|
||||||
if (raster != NULL)
|
if (raster != nullptr)
|
||||||
{
|
{
|
||||||
if (TIFFReadRGBAImageOriented(tif, w, h, raster, ORIENTATION_TOPLEFT, 0))
|
if (TIFFReadRGBAImageOriented(tif, w, h, raster, ORIENTATION_TOPLEFT, 0))
|
||||||
{
|
{
|
||||||
|
@ -1851,7 +1851,7 @@ bool Image::initWithWebpData(const unsigned char * data, ssize_t dataLen)
|
||||||
if (WebPDecode(static_cast<const uint8_t*>(data), dataLen, &config) != VP8_STATUS_OK)
|
if (WebPDecode(static_cast<const uint8_t*>(data), dataLen, &config) != VP8_STATUS_OK)
|
||||||
{
|
{
|
||||||
free(_data);
|
free(_data);
|
||||||
_data = NULL;
|
_data = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1941,21 +1941,21 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_bytep *row_pointers;
|
png_bytep *row_pointers;
|
||||||
|
|
||||||
fp = fopen(filePath.c_str(), "wb");
|
fp = fopen(filePath.c_str(), "wb");
|
||||||
CC_BREAK_IF(NULL == fp);
|
CC_BREAK_IF(nullptr == fp);
|
||||||
|
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
if (NULL == png_ptr)
|
if (nullptr == png_ptr)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
info_ptr = png_create_info_struct(png_ptr);
|
||||||
if (NULL == info_ptr)
|
if (nullptr == info_ptr)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_write_struct(&png_ptr, NULL);
|
png_destroy_write_struct(&png_ptr, nullptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA && CC_TARGET_PLATFORM != CC_PLATFORM_NACL)
|
#if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA && CC_TARGET_PLATFORM != CC_PLATFORM_NACL)
|
||||||
|
@ -1987,14 +1987,14 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_set_packing(png_ptr);
|
png_set_packing(png_ptr);
|
||||||
|
|
||||||
row_pointers = (png_bytep *)malloc(_height * sizeof(png_bytep));
|
row_pointers = (png_bytep *)malloc(_height * sizeof(png_bytep));
|
||||||
if(row_pointers == NULL)
|
if(row_pointers == nullptr)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasAlpha())
|
if (!hasAlpha())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)_height; i++)
|
for (int i = 0; i < (int)_height; i++)
|
||||||
{
|
{
|
||||||
|
@ -2004,14 +2004,14 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
free(row_pointers);
|
free(row_pointers);
|
||||||
row_pointers = NULL;
|
row_pointers = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isToRGB)
|
if (isToRGB)
|
||||||
{
|
{
|
||||||
unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char*)));
|
unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char*)));
|
||||||
if (NULL == pTempData)
|
if (nullptr == pTempData)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
@ -2036,7 +2036,7 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
free(row_pointers);
|
free(row_pointers);
|
||||||
row_pointers = NULL;
|
row_pointers = nullptr;
|
||||||
|
|
||||||
if (pTempData != nullptr)
|
if (pTempData != nullptr)
|
||||||
{
|
{
|
||||||
|
@ -2053,14 +2053,14 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
free(row_pointers);
|
free(row_pointers);
|
||||||
row_pointers = NULL;
|
row_pointers = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
png_write_end(png_ptr, info_ptr);
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
||||||
png_free(png_ptr, palette);
|
png_free(png_ptr, palette);
|
||||||
palette = NULL;
|
palette = nullptr;
|
||||||
|
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
|
||||||
|
@ -2085,7 +2085,7 @@ bool Image::saveImageToJPG(const std::string& filePath)
|
||||||
/* Now we can initialize the JPEG compression object. */
|
/* Now we can initialize the JPEG compression object. */
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
|
|
||||||
CC_BREAK_IF((outfile = fopen(filePath.c_str(), "wb")) == NULL);
|
CC_BREAK_IF((outfile = fopen(filePath.c_str(), "wb")) == nullptr);
|
||||||
|
|
||||||
jpeg_stdio_dest(&cinfo, outfile);
|
jpeg_stdio_dest(&cinfo, outfile);
|
||||||
|
|
||||||
|
@ -2103,7 +2103,7 @@ bool Image::saveImageToJPG(const std::string& filePath)
|
||||||
if (hasAlpha())
|
if (hasAlpha())
|
||||||
{
|
{
|
||||||
unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char)));
|
unsigned char *pTempData = static_cast<unsigned char*>(malloc(_width * _height * 3 * sizeof(unsigned char)));
|
||||||
if (NULL == pTempData)
|
if (nullptr == pTempData)
|
||||||
{
|
{
|
||||||
jpeg_finish_compress(&cinfo);
|
jpeg_finish_compress(&cinfo);
|
||||||
jpeg_destroy_compress(&cinfo);
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
|
|
@ -143,14 +143,8 @@ void RenderTextureSave::saveImage(cocos2d::Object *sender)
|
||||||
_target->saveToFile(png, Image::Format::PNG);
|
_target->saveToFile(png, Image::Format::PNG);
|
||||||
_target->saveToFile(jpg, Image::Format::JPG);
|
_target->saveToFile(jpg, Image::Format::JPG);
|
||||||
|
|
||||||
|
std::string fileName = FileUtils::getInstance()->getWritablePath() + jpg;
|
||||||
auto image = _target->newImage();
|
auto sprite = Sprite::create(fileName);
|
||||||
|
|
||||||
auto tex = Director::getInstance()->getTextureCache()->addImage(image, png);
|
|
||||||
|
|
||||||
CC_SAFE_DELETE(image);
|
|
||||||
|
|
||||||
auto sprite = Sprite::createWithTexture(tex);
|
|
||||||
|
|
||||||
sprite->setScale(0.3f);
|
sprite->setScale(0.3f);
|
||||||
addChild(sprite);
|
addChild(sprite);
|
||||||
|
|
Loading…
Reference in New Issue