2011-02-23 18:22:05 +08:00
|
|
|
/****************************************************************************
|
2014-01-07 11:25:07 +08:00
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
2018-01-29 16:25:32 +08:00
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
2011-02-23 18:22:05 +08:00
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
2014-05-17 05:36:00 +08:00
|
|
|
#import "platform/CCImage.h"
|
|
|
|
#import "platform/CCCommon.h"
|
2011-08-01 18:22:47 +08:00
|
|
|
#import <string>
|
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
|
2014-05-17 05:36:00 +08:00
|
|
|
#include <math.h>
|
2013-05-02 05:47:47 +08:00
|
|
|
|
2012-04-19 11:56:22 +08:00
|
|
|
NS_CC_BEGIN
|
2011-02-23 18:22:05 +08:00
|
|
|
|
2014-02-13 21:08:43 +08:00
|
|
|
bool cocos2d::Image::saveToFile(const std::string& filename, bool isToRGB)
|
2011-07-29 15:57:27 +08:00
|
|
|
{
|
2020-09-25 11:07:56 +08:00
|
|
|
//only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data
|
|
|
|
if (isCompressed() || (_pixelFormat != backend::PixelFormat::RGB8 && _pixelFormat != backend::PixelFormat::RGBA8))
|
2018-09-10 16:35:31 +08:00
|
|
|
{
|
2020-09-25 11:07:56 +08:00
|
|
|
CCLOG("cocos2d: Image: saveToFile is only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data for now");
|
2018-09-10 16:35:31 +08:00
|
|
|
return false;
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
bool saveToPNG = false;
|
|
|
|
bool needToCopyPixels = false;
|
2013-11-15 09:19:16 +08:00
|
|
|
|
2014-06-13 15:32:49 +08:00
|
|
|
std::string basename(filename);
|
|
|
|
std::transform(basename.begin(), basename.end(), basename.begin(), ::tolower);
|
|
|
|
if (std::string::npos != basename.find(".png"))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
saveToPNG = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int bitsPerComponent = 8;
|
2013-07-26 17:34:44 +08:00
|
|
|
int bitsPerPixel = hasAlpha() ? 32 : 24;
|
2013-12-24 15:49:58 +08:00
|
|
|
if ((! saveToPNG) || isToRGB)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
|
|
|
bitsPerPixel = 24;
|
|
|
|
}
|
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
int bytesPerRow = (bitsPerPixel/8) * _width;
|
|
|
|
int myDataLength = bytesPerRow * _height;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
unsigned char *pixels = _data;
|
2012-04-19 14:35:52 +08:00
|
|
|
|
|
|
|
// The data has alpha channel, and want to save it with an RGB png file,
|
2011-08-08 11:01:47 +08:00
|
|
|
// or want to save as jpg, remove the alpha channel.
|
2014-04-21 10:25:34 +08:00
|
|
|
if (hasAlpha() && bitsPerPixel == 24)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2015-12-16 14:02:55 +08:00
|
|
|
pixels = new (std::nothrow) unsigned char[myDataLength];
|
2012-04-19 14:35:52 +08:00
|
|
|
|
2013-06-15 14:03:30 +08:00
|
|
|
for (int i = 0; i < _height; ++i)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
for (int j = 0; j < _width; ++j)
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2013-06-15 14:03:30 +08:00
|
|
|
pixels[(i * _width + j) * 3] = _data[(i * _width + j) * 4];
|
|
|
|
pixels[(i * _width + j) * 3 + 1] = _data[(i * _width + j) * 4 + 1];
|
|
|
|
pixels[(i * _width + j) * 3 + 2] = _data[(i * _width + j) * 4 + 2];
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
needToCopyPixels = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// make data provider with data.
|
|
|
|
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
2013-12-24 15:49:58 +08:00
|
|
|
if (saveToPNG && hasAlpha() && (! isToRGB))
|
2012-04-19 14:35:52 +08:00
|
|
|
{
|
2019-07-26 17:09:00 +08:00
|
|
|
if (_hasPremultipliedAlpha)
|
|
|
|
{
|
|
|
|
bitmapInfo |= kCGImageAlphaPremultipliedLast;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bitmapInfo |= kCGImageAlphaLast;
|
|
|
|
}
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2013-12-18 17:47:20 +08:00
|
|
|
CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, pixels, myDataLength, nullptr);
|
2012-04-19 14:35:52 +08:00
|
|
|
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
2013-06-15 14:03:30 +08:00
|
|
|
CGImageRef iref = CGImageCreate(_width, _height,
|
2012-04-19 14:35:52 +08:00
|
|
|
bitsPerComponent, bitsPerPixel, bytesPerRow,
|
|
|
|
colorSpaceRef, bitmapInfo, provider,
|
2013-12-18 17:47:20 +08:00
|
|
|
nullptr, false,
|
2012-04-19 14:35:52 +08:00
|
|
|
kCGRenderingIntentDefault);
|
|
|
|
|
|
|
|
UIImage* image = [[UIImage alloc] initWithCGImage:iref];
|
|
|
|
|
|
|
|
CGImageRelease(iref);
|
|
|
|
CGColorSpaceRelease(colorSpaceRef);
|
|
|
|
CGDataProviderRelease(provider);
|
2016-05-05 22:00:28 +08:00
|
|
|
|
|
|
|
// NOTE: Prevent memory leak. Requires ARC enabled.
|
|
|
|
@autoreleasepool {
|
|
|
|
NSData *data;
|
|
|
|
if (saveToPNG) {
|
|
|
|
data = UIImagePNGRepresentation(image);
|
|
|
|
} else {
|
|
|
|
data = UIImageJPEGRepresentation(image, 1.0f);
|
|
|
|
}
|
|
|
|
[data writeToFile:[NSString stringWithUTF8String:filename.c_str()] atomically:YES];
|
2012-04-19 14:35:52 +08:00
|
|
|
}
|
2016-05-05 22:00:28 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
[image release];
|
2016-05-05 22:00:28 +08:00
|
|
|
|
2012-04-19 14:35:52 +08:00
|
|
|
if (needToCopyPixels)
|
|
|
|
{
|
|
|
|
delete [] pixels;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2011-07-29 15:57:27 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 11:56:22 +08:00
|
|
|
NS_CC_END
|