mirror of https://github.com/axmolengine/axmol.git
fixed #642: CCRenderTexture::saveBuffer() works ok on iOS
This commit is contained in:
parent
08b25229ac
commit
41ea2e98a1
|
@ -105,54 +105,53 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
size_t bpp = CGImageGetBitsPerComponent(image);
|
size_t bpp = CGImageGetBitsPerComponent(image);
|
||||||
colorSpace = CGImageGetColorSpace(image);
|
colorSpace = CGImageGetColorSpace(image);
|
||||||
|
|
||||||
if(colorSpace) {
|
if(colorSpace)
|
||||||
|
{
|
||||||
if(hasAlpha || bpp >= 8)
|
if(hasAlpha || bpp >= 8)
|
||||||
|
{
|
||||||
pixelFormat = kCCTexture2DPixelFormat_Default;
|
pixelFormat = kCCTexture2DPixelFormat_Default;
|
||||||
else {
|
}
|
||||||
//CCLOG(@"cocos2d: CCTexture2D: Using RGB565 texture since image has no alpha");
|
else
|
||||||
|
{
|
||||||
pixelFormat = kCCTexture2DPixelFormat_RGB565;
|
pixelFormat = kCCTexture2DPixelFormat_RGB565;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// NOTE: No colorspace means a mask image
|
// NOTE: No colorspace means a mask image
|
||||||
//CCLOG(@"cocos2d: CCTexture2D: Using A8 texture since image is a mask");
|
|
||||||
pixelFormat = kCCTexture2DPixelFormat_A8;
|
pixelFormat = kCCTexture2DPixelFormat_A8;
|
||||||
}
|
}
|
||||||
|
|
||||||
imageSize.width = CGImageGetWidth(image);
|
imageSize.width = CGImageGetWidth(image);
|
||||||
imageSize.height = CGImageGetHeight(image);
|
imageSize.height = CGImageGetHeight(image);
|
||||||
//imageSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));
|
|
||||||
|
|
||||||
// Create the bitmap graphics context
|
// Create the bitmap graphics context
|
||||||
|
|
||||||
switch(pixelFormat) {
|
switch(pixelFormat)
|
||||||
|
{
|
||||||
case kCCTexture2DPixelFormat_RGBA8888:
|
case kCCTexture2DPixelFormat_RGBA8888:
|
||||||
case kCCTexture2DPixelFormat_RGBA4444:
|
case kCCTexture2DPixelFormat_RGBA4444:
|
||||||
case kCCTexture2DPixelFormat_RGB5A1:
|
case kCCTexture2DPixelFormat_RGB5A1:
|
||||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
//data = malloc(POTHigh * POTWide * 4);
|
|
||||||
data = new unsigned char[POTHigh * POTWide * 4];
|
data = new unsigned char[POTHigh * POTWide * 4];
|
||||||
info = hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast;
|
info = hasAlpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNoneSkipLast;
|
||||||
// info = kCGImageAlphaPremultipliedLast; // issue #886. This patch breaks BMP images.
|
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kCCTexture2DPixelFormat_RGB565:
|
case kCCTexture2DPixelFormat_RGB565:
|
||||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||||
//data = malloc(POTHigh * POTWide * 4);
|
|
||||||
data = new unsigned char[POTHigh * POTWide * 4];
|
data = new unsigned char[POTHigh * POTWide * 4];
|
||||||
info = kCGImageAlphaNoneSkipLast;
|
info = kCGImageAlphaNoneSkipLast;
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, 4 * POTWide, colorSpace, info | kCGBitmapByteOrder32Big);
|
||||||
CGColorSpaceRelease(colorSpace);
|
CGColorSpaceRelease(colorSpace);
|
||||||
break;
|
break;
|
||||||
case kCCTexture2DPixelFormat_A8:
|
case kCCTexture2DPixelFormat_A8:
|
||||||
//data = malloc(POTHigh * POTWide);
|
|
||||||
data = new unsigned char[POTHigh * POTWide];
|
data = new unsigned char[POTHigh * POTWide];
|
||||||
info = kCGImageAlphaOnly;
|
info = kCGImageAlphaOnly;
|
||||||
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
|
context = CGBitmapContextCreate(data, POTWide, POTHigh, 8, POTWide, NULL, info);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//[NSException raise:NSInternalInconsistencyException format:@"Invalid pixel format"];
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,82 +161,79 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
rect.origin.x = 0;
|
rect.origin.x = 0;
|
||||||
rect.origin.y = 0;
|
rect.origin.y = 0;
|
||||||
|
|
||||||
//CGContextClearRect(context, CGRectMake(0, 0, POTWide, POTHigh));
|
|
||||||
CGContextClearRect(context, rect);
|
CGContextClearRect(context, rect);
|
||||||
CGContextTranslateCTM(context, 0, POTHigh - imageSize.height);
|
CGContextTranslateCTM(context, 0, POTHigh - imageSize.height);
|
||||||
//CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
|
|
||||||
rect.size.width = CGImageGetWidth(image);
|
rect.size.width = CGImageGetWidth(image);
|
||||||
rect.size.height = CGImageGetHeight(image);
|
rect.size.height = CGImageGetHeight(image);
|
||||||
rect.origin.x = 0;
|
rect.origin.x = 0;
|
||||||
rect.origin.y = 0;
|
rect.origin.y = 0;
|
||||||
//CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image);
|
|
||||||
CGContextDrawImage(context, rect, image);
|
CGContextDrawImage(context, rect, image);
|
||||||
|
|
||||||
// Repack the pixel data into the right format
|
// Repack the pixel data into the right format
|
||||||
|
|
||||||
if(pixelFormat == kCCTexture2DPixelFormat_RGB565) {
|
if(pixelFormat == kCCTexture2DPixelFormat_RGB565)
|
||||||
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
|
||||||
//tempData = malloc(POTHigh * POTWide * 2);
|
|
||||||
tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
inPixel32 = (unsigned int*)data;
|
inPixel32 = (unsigned int*)data;
|
||||||
outPixel16 = (unsigned short*)tempData;
|
outPixel16 = (unsigned short*)tempData;
|
||||||
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
||||||
|
{
|
||||||
*outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0);
|
*outPixel16++ = ((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | ((((*inPixel32 >> 8) & 0xFF) >> 2) << 5) | ((((*inPixel32 >> 16) & 0xFF) >> 3) << 0);
|
||||||
//free(data);
|
}
|
||||||
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (pixelFormat == kCCTexture2DPixelFormat_RGBA4444) {
|
else if (pixelFormat == kCCTexture2DPixelFormat_RGBA4444)
|
||||||
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
|
||||||
//tempData = malloc(POTHigh * POTWide * 2);
|
|
||||||
tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
inPixel32 = (unsigned int*)data;
|
inPixel32 = (unsigned int*)data;
|
||||||
outPixel16 = (unsigned short*)tempData;
|
outPixel16 = (unsigned short*)tempData;
|
||||||
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
||||||
|
{
|
||||||
*outPixel16++ =
|
*outPixel16++ =
|
||||||
((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R
|
((((*inPixel32 >> 0) & 0xFF) >> 4) << 12) | // R
|
||||||
((((*inPixel32 >> 8) & 0xFF) >> 4) << 8) | // G
|
((((*inPixel32 >> 8) & 0xFF) >> 4) << 8) | // G
|
||||||
((((*inPixel32 >> 16) & 0xFF) >> 4) << 4) | // B
|
((((*inPixel32 >> 16) & 0xFF) >> 4) << 4) | // B
|
||||||
((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A
|
((((*inPixel32 >> 24) & 0xFF) >> 4) << 0); // A
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//free(data);
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (pixelFormat == kCCTexture2DPixelFormat_RGB5A1) {
|
else if (pixelFormat == kCCTexture2DPixelFormat_RGB5A1)
|
||||||
|
{
|
||||||
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
|
//Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
|
||||||
//tempData = malloc(POTHigh * POTWide * 2);
|
|
||||||
tempData = new unsigned char[POTHigh * POTWide * 2];
|
tempData = new unsigned char[POTHigh * POTWide * 2];
|
||||||
inPixel32 = (unsigned int*)data;
|
inPixel32 = (unsigned int*)data;
|
||||||
outPixel16 = (unsigned short*)tempData;
|
outPixel16 = (unsigned short*)tempData;
|
||||||
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
for(i = 0; i < POTWide * POTHigh; ++i, ++inPixel32)
|
||||||
|
{
|
||||||
*outPixel16++ =
|
*outPixel16++ =
|
||||||
((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R
|
((((*inPixel32 >> 0) & 0xFF) >> 3) << 11) | // R
|
||||||
((((*inPixel32 >> 8) & 0xFF) >> 3) << 6) | // G
|
((((*inPixel32 >> 8) & 0xFF) >> 3) << 6) | // G
|
||||||
((((*inPixel32 >> 16) & 0xFF) >> 3) << 1) | // B
|
((((*inPixel32 >> 16) & 0xFF) >> 3) << 1) | // B
|
||||||
((((*inPixel32 >> 24) & 0xFF) >> 7) << 0); // A
|
((((*inPixel32 >> 24) & 0xFF) >> 7) << 0); // A
|
||||||
|
}
|
||||||
|
|
||||||
//free(data);
|
|
||||||
delete[] data;
|
delete[] data;
|
||||||
data = tempData;
|
data = tempData;
|
||||||
}
|
}
|
||||||
//self = [self initWithData:data pixelFormat:pixelFormat pixelsWide:POTWide pixelsHigh:POTHigh contentSize:imageSize];
|
|
||||||
|
|
||||||
// should be after calling super init
|
// should be after calling super init
|
||||||
//s_imageInfo.isPremultipliedAlpha = (info == kCGImageAlphaPremultipliedLast || info == kCGImageAlphaPremultipliedFirst);
|
|
||||||
pImageInfo->isPremultipliedAlpha = true;
|
pImageInfo->isPremultipliedAlpha = true;
|
||||||
pImageInfo->hasAlpha = true;
|
pImageInfo->hasAlpha = true;
|
||||||
//s_imageInfo.hasAlpha = hasAlpha;
|
|
||||||
pImageInfo->bitsPerComponent = bpp;
|
pImageInfo->bitsPerComponent = bpp;
|
||||||
pImageInfo->width = imageSize.width;
|
pImageInfo->width = imageSize.width;
|
||||||
pImageInfo->height = imageSize.height;
|
pImageInfo->height = imageSize.height;
|
||||||
|
|
||||||
if (pImageInfo->data)
|
if (pImageInfo->data)
|
||||||
{
|
{
|
||||||
delete []pImageInfo->data;
|
delete [] pImageInfo->data;
|
||||||
}
|
}
|
||||||
pImageInfo->data = data;
|
pImageInfo->data = data;
|
||||||
|
|
||||||
|
@ -247,25 +243,17 @@ static bool _initPremultipliedATextureWithImage(CGImageRef image, NSUInteger POT
|
||||||
|
|
||||||
static bool _initWithImage(CGImageRef CGImage, tImageInfo *pImageinfo)
|
static bool _initWithImage(CGImageRef CGImage, tImageInfo *pImageinfo)
|
||||||
{
|
{
|
||||||
NSUInteger POTWide, POTHigh;
|
NSUInteger POTWide, POTHigh;
|
||||||
|
|
||||||
if(CGImage == NULL) {
|
if(CGImage == NULL)
|
||||||
//CCLOG(@"cocos2d: CCTexture2D. Can't create Texture. ccxImage is nil");
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CCConfiguration *conf = [CCConfiguration sharedConfiguration];
|
|
||||||
// cocos2d::CCConfiguration *conf = cocos2d::CCConfiguration::sharedConfiguration();
|
|
||||||
|
|
||||||
POTWide = CGImageGetWidth(CGImage);
|
POTWide = CGImageGetWidth(CGImage);
|
||||||
POTHigh = CGImageGetHeight(CGImage);
|
POTHigh = CGImageGetHeight(CGImage);
|
||||||
|
|
||||||
// unsigned maxTextureSize = conf->getMaxTextureSize();
|
// always load premultiplied images
|
||||||
// if( POTHigh > maxTextureSize || POTWide > maxTextureSize ) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// always load premultiplied images
|
|
||||||
_initPremultipliedATextureWithImage(CGImage, POTWide, POTHigh, pImageinfo);
|
_initPremultipliedATextureWithImage(CGImage, POTWide, POTHigh, pImageinfo);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -278,7 +266,7 @@ static bool _initWithFile(const char* path, tImageInfo *pImageinfo)
|
||||||
UIImage *png;
|
UIImage *png;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
// convert jpg to png before loading the texture
|
// convert jpg to png before loading the texture
|
||||||
|
|
||||||
NSString *fullPath = [NSString stringWithUTF8String:path];
|
NSString *fullPath = [NSString stringWithUTF8String:path];
|
||||||
jpg = [[UIImage alloc] initWithContentsOfFile: fullPath];
|
jpg = [[UIImage alloc] initWithContentsOfFile: fullPath];
|
||||||
|
@ -298,9 +286,10 @@ static bool _initWithData(void * pBuffer, int length, tImageInfo *pImageinfo)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if (pBuffer) {
|
if (pBuffer)
|
||||||
CGImageRef CGImage;
|
{
|
||||||
NSData *data;
|
CGImageRef CGImage;
|
||||||
|
NSData *data;
|
||||||
|
|
||||||
data = [NSData dataWithBytes:pBuffer length:length];
|
data = [NSData dataWithBytes:pBuffer length:length];
|
||||||
CGImage = [[UIImage imageWithData:data] CGImage];
|
CGImage = [[UIImage imageWithData:data] CGImage];
|
||||||
|
@ -317,14 +306,18 @@ static bool _isValidFontName(const char *fontName)
|
||||||
|
|
||||||
NSString *fontNameNS = [NSString stringWithUTF8String:fontName];
|
NSString *fontNameNS = [NSString stringWithUTF8String:fontName];
|
||||||
|
|
||||||
for (NSString *familiName in [UIFont familyNames]) {
|
for (NSString *familiName in [UIFont familyNames])
|
||||||
if ([familiName isEqualToString:fontNameNS]) {
|
{
|
||||||
|
if ([familiName isEqualToString:fontNameNS])
|
||||||
|
{
|
||||||
ret = true;
|
ret = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(NSString *font in [UIFont fontNamesForFamilyName: familiName]){
|
for(NSString *font in [UIFont fontNamesForFamilyName: familiName])
|
||||||
if ([font isEqualToString: fontNameNS]){
|
{
|
||||||
|
if ([font isEqualToString: fontNameNS])
|
||||||
|
{
|
||||||
ret = true;
|
ret = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -429,7 +422,6 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
|
||||||
#if CC_FONT_LABEL_SUPPORT
|
#if CC_FONT_LABEL_SUPPORT
|
||||||
else // ZFont class
|
else // ZFont class
|
||||||
{
|
{
|
||||||
//[str drawInRect:CGRectMake(0, 0, dim.width, dim.height) withZFont:font lineBreakMode:UILineBreakModeWordWrap alignment:align];
|
|
||||||
[FontLabelStringDrawingHelper drawInRect:str rect:CGRectMake(0, 0, dim.width, dim.height) withZFont:font lineBreakMode:UILineBreakModeWordWrap alignment:align];
|
[FontLabelStringDrawingHelper drawInRect:str rect:CGRectMake(0, 0, dim.width, dim.height) withZFont:font lineBreakMode:UILineBreakModeWordWrap alignment:align];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -485,20 +477,72 @@ bool CCImage::initWithImageData(void * pData,
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
CC_BREAK_IF(! pData || nDataLen <= 0);
|
CC_BREAK_IF(! pData || nDataLen <= 0);
|
||||||
bRet = _initWithData(pData, nDataLen, &info);
|
if (eFmt == kFmtRawData)
|
||||||
|
{
|
||||||
|
bRet = _initWithRawData(pData, nDataLen, nWidth, nHeight, nBitsPerComponent);
|
||||||
|
}
|
||||||
|
else // init with png or jpg file data
|
||||||
|
{
|
||||||
|
bRet = _initWithData(pData, nDataLen, &info);
|
||||||
|
if (bRet)
|
||||||
|
{
|
||||||
|
m_nHeight = (short)info.height;
|
||||||
|
m_nWidth = (short)info.width;
|
||||||
|
m_nBitsPerComponent = info.bitsPerComponent;
|
||||||
|
m_bHasAlpha = info.hasAlpha;
|
||||||
|
m_bPreMulti = info.isPremultipliedAlpha;
|
||||||
|
m_pData = info.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
if (bRet)
|
|
||||||
{
|
|
||||||
m_nHeight = (short)info.height;
|
|
||||||
m_nWidth = (short)info.width;
|
|
||||||
m_nBitsPerComponent = info.bitsPerComponent;
|
|
||||||
m_bHasAlpha = info.hasAlpha;
|
|
||||||
m_bPreMulti = info.isPremultipliedAlpha;
|
|
||||||
m_pData = info.data;
|
|
||||||
}
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCImage::_initWithRawData(void *pData, int nDatalen, int nWidth, int nHeight, int nBitsPerComponent)
|
||||||
|
{
|
||||||
|
bool bRet = false;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
CC_BREAK_IF(0 == nWidth || 0 == nHeight);
|
||||||
|
|
||||||
|
m_nBitsPerComponent = nBitsPerComponent;
|
||||||
|
m_nHeight = (short)nHeight;
|
||||||
|
m_nWidth = (short)nWidth;
|
||||||
|
m_bHasAlpha = true;
|
||||||
|
|
||||||
|
// only RGBA8888 surported
|
||||||
|
int nBytesPerComponent = 4;
|
||||||
|
int nSize = nHeight * nWidth * nBytesPerComponent;
|
||||||
|
m_pData = new unsigned char[nSize];
|
||||||
|
CC_BREAK_IF(! m_pData);
|
||||||
|
memcpy(m_pData, pData, nSize);
|
||||||
|
|
||||||
|
bRet = true;
|
||||||
|
} while (0);
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCImage::_initWithJpgData(void *pData, int nDatalen)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCImage::_initWithPngData(void *pData, int nDatalen)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCImage::_saveImageToPNG(const char *pszFilePath, bool bIsToRGB)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCImage::_saveImageToJPG(const char *pszFilePath)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
bool CCImage::initWithString(
|
bool CCImage::initWithString(
|
||||||
const char * pText,
|
const char * pText,
|
||||||
int nWidth /* = 0 */,
|
int nWidth /* = 0 */,
|
||||||
|
@ -527,7 +571,87 @@ bool CCImage::initWithString(
|
||||||
|
|
||||||
bool CCImage::saveToFile(const char *pszFilePath, bool bIsToRGB)
|
bool CCImage::saveToFile(const char *pszFilePath, bool bIsToRGB)
|
||||||
{
|
{
|
||||||
return false;
|
bool saveToPNG = false;
|
||||||
|
bool needToCopyPixels = false;
|
||||||
|
std::string filePath(pszFilePath);
|
||||||
|
if (std::string::npos != filePath.find(".png"))
|
||||||
|
{
|
||||||
|
saveToPNG = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bitsPerComponent = 8;
|
||||||
|
int bitsPerPixel = m_bHasAlpha ? 32 : 24;
|
||||||
|
if ((! saveToPNG) || bIsToRGB)
|
||||||
|
{
|
||||||
|
bitsPerPixel = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytesPerRow = (bitsPerPixel/8) * m_nWidth;
|
||||||
|
int myDataLength = bytesPerRow * m_nHeight;
|
||||||
|
|
||||||
|
unsigned char *pixels = m_pData;
|
||||||
|
|
||||||
|
// 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 ((saveToPNG && m_bHasAlpha && bIsToRGB)
|
||||||
|
|| (! saveToPNG))
|
||||||
|
{
|
||||||
|
pixels = new unsigned char[myDataLength];
|
||||||
|
|
||||||
|
for (int i = 0; i < m_nHeight; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < m_nWidth; ++j)
|
||||||
|
{
|
||||||
|
pixels[(i * m_nWidth + j) * 3] = m_pData[(i * m_nWidth + j) * 4];
|
||||||
|
pixels[(i * m_nWidth + j) * 3 + 1] = m_pData[(i * m_nWidth + j) * 4 + 1];
|
||||||
|
pixels[(i * m_nWidth + j) * 3 + 2] = m_pData[(i * m_nWidth + j) * 4 + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
needToCopyPixels = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make data provider with data.
|
||||||
|
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
||||||
|
if (saveToPNG && m_bHasAlpha && (! bIsToRGB))
|
||||||
|
{
|
||||||
|
bitmapInfo |= kCGImageAlphaPremultipliedLast;
|
||||||
|
}
|
||||||
|
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, myDataLength, NULL);
|
||||||
|
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
||||||
|
CGImageRef iref = CGImageCreate(m_nWidth, m_nHeight,
|
||||||
|
bitsPerComponent, bitsPerPixel, bytesPerRow,
|
||||||
|
colorSpaceRef, bitmapInfo, provider,
|
||||||
|
NULL, false,
|
||||||
|
kCGRenderingIntentDefault);
|
||||||
|
|
||||||
|
UIImage* image = [[UIImage alloc] initWithCGImage:iref];
|
||||||
|
|
||||||
|
CGImageRelease(iref);
|
||||||
|
CGColorSpaceRelease(colorSpaceRef);
|
||||||
|
CGDataProviderRelease(provider);
|
||||||
|
|
||||||
|
NSData *data;
|
||||||
|
|
||||||
|
if (saveToPNG)
|
||||||
|
{
|
||||||
|
data = UIImagePNGRepresentation(image);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = UIImageJPEGRepresentation(image, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data writeToFile:[NSString stringWithUTF8String:pszFilePath] atomically:YES];
|
||||||
|
|
||||||
|
[image release];
|
||||||
|
|
||||||
|
if (needToCopyPixels)
|
||||||
|
{
|
||||||
|
delete [] pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CC_END;
|
NS_CC_END;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
089538e21098633ff475d29aa721c886c2eed848
|
b21283100ca056134301332a759b4d1ad747f4e2
|
Loading…
Reference in New Issue