如何在cocos2d中截屏07/23/20110 Comments 使用SDK截屏比较简单,代码如下:UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();但使用SDK截屏无法得到cocos2d图像,这是因为cocos2d是用OpenGL渲染的,所以用SDK截屏只能得到空白的一张图片.OpenGL有一个渲染屏幕上所有像素点的buffer(缓冲区),使用glReadPixels函数来读取buffer中的像素数据,然后用读取的数据创建一个UIImage,然后就可以保存UIImage了.以下代码来自cocos2d官方论坛,感谢ForzeField:#import
@interface AWScreenshot :NSObject
{
}
+(CGImageRef) takeAsCGImage;
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
+(UIImage*) takeAsImage;
#else
+(CGImageRef) takeAsImage;
#endif
+(CCTexture2D*) takeAsTexture;
@end/*
* AWSuite: http://forzefield.com
*
* Copyright (c) 2010 ForzeField Studios S.L.
*
* 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 "AWScreenshot.h"
#import "CCDirector.h"
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
#import "CCDirectorIOS.h"
#import "ccMacros.h"
#define AWIMAGE UIImage*
#else
#import "CCDirectorMac.h"
#define AWIMAGE CGImageRef
#endif
@implementation AWScreenshot
#pragma mark -
#pragma mark Take screenshot as data
+(CGImageRef) takeAsCGImage
{
CCDirector *director =[CCDirector sharedDirector];
CGSize displaySize =[director displaySizeInPixels];
CGSize winSize =[director winSizeInPixels];
// Create buffer for pixels
GLuint bufferLength = displaySize.width * displaySize.height *4;
GLubyte* buffer =(GLubyte*)malloc(bufferLength);
// Read Pixels from OpenGL
glReadPixels(0, 0, displaySize.width, displaySize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer, bufferLength, NULL);
// Configure image
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGImageRef iref = CGImageCreate(displaySize.width, displaySize.height, 8, 32, displaySize.width *4, colorSpaceRef, kCGBitmapByteOrderDefault, provider, NULL, NO, kCGRenderingIntentDefault);
// Create buffer for output image
uint32_t* pixels =(uint32_t*)malloc(winSize.width * winSize.height *4);
CGContextRef context = CGBitmapContextCreate(pixels, winSize.width, winSize.height, 8, winSize.width *4, colorSpaceRef, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
// Transform
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
CGContextTranslateCTM(context, 0, displaySize.height);
CGContextScaleCTM(context, 1, -1);
switch([director deviceOrientation])
{
case kCCDeviceOrientationPortrait:break;
case kCCDeviceOrientationPortraitUpsideDown:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(180));
CGContextTranslateCTM(context, -displaySize.width, -displaySize.height);
break;
case kCCDeviceOrientationLandscapeLeft:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(-90));
CGContextTranslateCTM(context, -displaySize.height, 0);
break;
case kCCDeviceOrientationLandscapeRight:
CGContextRotateCTM(context, CC_DEGREES_TO_RADIANS(90));
CGContextTranslateCTM(context, displaySize.height-displaySize.width, -displaySize.height);
break;
}
// Render
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, displaySize.width, displaySize.height), iref);
#else
CGContextTranslateCTM(context, 0, winSize.height);
CGContextScaleCTM(context, 1, -1);
// Render
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, winSize.width, winSize.height), iref);
#endif
// Create image
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// Dealloc
CGDataProviderRelease(provider);
CGImageRelease(iref);
CGColorSpaceRelease(colorSpaceRef);
CGContextRelease(context);
free(buffer);
free(pixels);
return imageRef;
}
#pragma mark -
#pragma mark Take screenshot as image
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
+(UIImage*) takeAsImage
{
CGImageRef imageRef =[self takeAsCGImage];
UIImage *outputImage =[[[UIImage alloc] initWithCGImage:imageRef] autorelease];
CGImageRelease(imageRef);
return outputImage;
}
#else
+(CGImageRef) takeAsImage
{
return[self takeAsCGImage];
}
#endif
#pragma mark -
#pragma mark Take screenshot as texture
+(CCTexture2D*) takeAsTexture
{
AWIMAGE imageRef =[self takeAsImage];
CCTexture2D *outputTexture =[[[CCTexture2D alloc] initWithImage:imageRef] autorelease];
#ifndef __IPHONE_OS_VERSION_MAX_ALLOWED
CGImageRelease(imageRef);
#endif
return outputTexture;
}
@end这种通过OpenGL buffer截屏的方法同样适用于其他基于OpenGL的平台,如android的 andEngine .
最后保存图片到照片库:UIImage *image;
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);