2019-11-23 20:27:39 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
|
|
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
https://axys1.github.io/
|
2019-11-23 20:27:39 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
#import "platform/CCImage.h"
|
|
|
|
#import "platform/CCCommon.h"
|
2021-06-03 02:34:02 +08:00
|
|
|
#import "platform/CCFileUtils.h"
|
2019-11-23 20:27:39 +08:00
|
|
|
#import <string>
|
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
#import <UIKit/UIKit.h>
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_BEGIN
|
2019-11-23 20:27:39 +08:00
|
|
|
|
2022-08-08 18:02:17 +08:00
|
|
|
bool ax::Image::saveToFile(std::string_view filename, bool isToRGB)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
// only support for backend::PixelFormat::RGB8 or backend::PixelFormat::RGBA8 uncompressed data
|
2020-09-25 11:07:56 +08:00
|
|
|
if (isCompressed() || (_pixelFormat != backend::PixelFormat::RGB8 && _pixelFormat != backend::PixelFormat::RGBA8))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2022-07-16 10:43:05 +08:00
|
|
|
AXLOG("cocos2d: Image: saveToFile is only support for backend::PixelFormat::RGB8 or "
|
2021-12-31 12:12:40 +08:00
|
|
|
"backend::PixelFormat::RGBA8 uncompressed data for now");
|
2019-11-23 20:27:39 +08:00
|
|
|
return false;
|
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
bool saveToPNG = false;
|
2019-11-23 20:27:39 +08:00
|
|
|
bool needToCopyPixels = false;
|
|
|
|
|
|
|
|
std::string basename(filename);
|
|
|
|
std::transform(basename.begin(), basename.end(), basename.begin(), ::tolower);
|
|
|
|
if (std::string::npos != basename.find(".png"))
|
|
|
|
{
|
|
|
|
saveToPNG = true;
|
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
|
|
|
int bitsPerComponent = 8;
|
|
|
|
int bitsPerPixel = hasAlpha() ? 32 : 24;
|
|
|
|
if ((!saveToPNG) || isToRGB)
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
|
|
|
bitsPerPixel = 24;
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int bytesPerRow = (bitsPerPixel / 8) * _width;
|
2019-11-23 20:27:39 +08:00
|
|
|
int myDataLength = bytesPerRow * _height;
|
2021-12-31 12:12:40 +08:00
|
|
|
|
|
|
|
unsigned char* pixels = _data;
|
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
// The data has alpha channel, and want to save it with an RGB png file,
|
|
|
|
// or want to save as jpg, remove the alpha channel.
|
|
|
|
if (hasAlpha() && bitsPerPixel == 24)
|
|
|
|
{
|
2021-12-08 00:11:53 +08:00
|
|
|
pixels = new unsigned char[myDataLength];
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
for (int i = 0; i < _height; ++i)
|
|
|
|
{
|
|
|
|
for (int j = 0; j < _width; ++j)
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
pixels[(i * _width + j) * 3] = _data[(i * _width + j) * 4];
|
2019-11-23 20:27:39 +08:00
|
|
|
pixels[(i * _width + j) * 3 + 1] = _data[(i * _width + j) * 4 + 1];
|
|
|
|
pixels[(i * _width + j) * 3 + 2] = _data[(i * _width + j) * 4 + 2];
|
|
|
|
}
|
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
needToCopyPixels = true;
|
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
// make data provider with data.
|
|
|
|
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
2021-12-31 12:12:40 +08:00
|
|
|
if (saveToPNG && hasAlpha() && (!isToRGB))
|
2019-11-23 20:27:39 +08:00
|
|
|
{
|
2020-11-24 18:10:28 +08:00
|
|
|
bitmapInfo |= kCGImageAlphaLast;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
CGDataProviderRef provider = CGDataProviderCreateWithData(nullptr, pixels, myDataLength, nullptr);
|
|
|
|
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
|
|
|
CGImageRef iref = CGImageCreate(_width, _height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef,
|
|
|
|
bitmapInfo, provider, nullptr, false, kCGRenderingIntentDefault);
|
|
|
|
|
|
|
|
UIImage* image = [[UIImage alloc] initWithCGImage:iref];
|
|
|
|
|
|
|
|
CGImageRelease(iref);
|
2019-11-23 20:27:39 +08:00
|
|
|
CGColorSpaceRelease(colorSpaceRef);
|
|
|
|
CGDataProviderRelease(provider);
|
|
|
|
|
|
|
|
// NOTE: Prevent memory leak. Requires ARC enabled.
|
2021-12-31 12:12:40 +08:00
|
|
|
@autoreleasepool
|
|
|
|
{
|
|
|
|
NSData* data;
|
|
|
|
if (saveToPNG)
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
data = UIImagePNGRepresentation(image);
|
2021-12-31 12:12:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-23 20:27:39 +08:00
|
|
|
data = UIImageJPEGRepresentation(image, 1.0f);
|
|
|
|
}
|
2021-06-03 02:34:02 +08:00
|
|
|
|
|
|
|
auto outStream = FileUtils::getInstance()->openFileStream(filename, FileStream::Mode::WRITE);
|
|
|
|
outStream->write(data.bytes, data.length);
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[image release];
|
|
|
|
|
|
|
|
if (needToCopyPixels)
|
|
|
|
{
|
2021-12-31 12:12:40 +08:00
|
|
|
delete[] pixels;
|
2019-11-23 20:27:39 +08:00
|
|
|
}
|
2021-12-31 12:12:40 +08:00
|
|
|
|
2019-11-23 20:27:39 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-11 17:50:21 +08:00
|
|
|
NS_AX_END
|