适用平台:iOS6.0.1,Xcode4.5.2,cocos2d v2.1 beta4(cocos2d-iphone)
在游戏过程中,有时候会希望得到当前界面的截屏。
比如,可以玩家可以把自己过关的场面通过社交网络分享给朋友,或者开发者可以研究玩家在游戏过程中所关注的场景。
在iphone应用中有两种方式获得游戏界面的截屏
方式1(针对一般的UIView应用):
step1:添加QuartzCore框架
step2:在文件中添加#import
step3:添加以下两个方法:
- (UIImage*)captureView:(UIView *)view
{
CGRect rect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
return img;
}
- (void)saveScreenshotToPhotosAlbum:(UIView *)view
{ UIImageWriteToSavedPhotosAlbum([self captureView:view], nil, nil, nil);
}
通过以上方法,我们可以获得一个UIImage类型的屏幕截图,并保存到photos album中。只要在需要的地方调用以上方法就好了。
而另一种方法则是获取OpenGL 视图的截图,也是我们重点说明的。
这里提供了一个简单的示例,下载地址:
下载完后可以按以下步骤来实现
step1:创建一个新的项目ScreenShot(或者在自己已有的项目中),将Screenshot.h和bg.png,bg-hd.png文件拖到项目中。
Screenshot.h中的内容就是如何获取OpenGL截图,感兴趣的朋友可以仔细研究其中的内容
step2:在HelloWorldLayer.m的文件顶部添加以下代码:
#import "Screenshot.h"
step3:添加以下几个方法:
-(void)takeScreenshots{
CCSprite* sprite = [CCSprite spriteWithTexture:[Screenshot takeAsTexture2D]];
sprite.position = ccp(240,160);
sprite.scale = 0.5;
[self addChild:sprite z:0 tag:0];
}
-(void)saveToPhotosAlbum{
UIImageWriteToSavedPhotosAlbum([Screenshot takeAsUIImage], nil, nil, nil);
}
-(void)addBg{
CGSize size = [CCDirector sharedDirector].winSize;
CCSprite *bg = [CCSprite spriteWithFile:@"bg.png"];
bg.position = ccp(size.width/2,size.height/2);
[self addChild:bg z:-1];
}
-(void)addMenu{
CGSize size = [CCDirector sharedDirector].winSize;
[CCMenuItemFont setFontSize:20];
CCMenuItemFont *item = [CCMenuItemFont itemWithString:@"Take a screen shot" target:selfselector:@selector(takeScreenshots)];
CCMenuItemFont *item2 = [CCMenuItemFont itemWithString:@"Save to the photo library"target:self selector:@selector(saveToPhotosAlbum)];
item.position = ccp(size.width*0.8,size.height*0.9);
item2.position = ccp(size.width*0.8,size.height*0.8);
CCMenu *menu = [CCMenu menuWithItems:item,item2, nil];
menu.position = ccp(0,0);
[self addChild:menu z:-1];
}
以上代码中,addBg方法最简单,它只是添加了一个背景图片。addMenu方法则添加了一个菜单,其中包含两个菜单项,一个用于截屏,一个用于将截屏保存到photo albums中(当然也可以二合一)
而takeScreenshots方法中,调用Screenshot的takeAsTexture2D方法获取一个纹理,然后用CCSprite的类方法来创建一个精灵,并添加到层中
saveToPhotosAlbum方法很简单,使用UIImageWriteToSavedPhotosAlbum方法将截屏保存到photos album中。
step4.在init方法中添加以下代码:
[self addBg];
[self addMenu];
step5.编译运行。
触碰Take a screen shot标签就会生成一个屏幕截图,并以0.5的比例(只是为了显示方便)显示在屏幕中。
如果查看photos library,也会看到所保存的截图(不过要注意到该方法中本身调用了截屏方法,所以会看到图中有图)。
最后,以上方法忽略了屏幕分辨率的问题,不过要解决起来也是很简单的,这里就不废话了
网上的第三种方式,和方式2很类似:
使用下面的两个方法也可以:
- (UIImage*) getGLScreenshot {
NSInteger myDataLength = 320 * 480 * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <480; y++)
{
for(int x = 0; x <320 * 4; x++)
{
buffer2[(479 - y) * 320 * 4 + x] = buffer[y * 4 * 320 + x];
}
}
// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
buffer2, myDataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * 320;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// make the cgimage
CGImageRef imageRef = CGImageCreate(320, 480, bitsPerComponent,
bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider,
NULL, NO, renderingIntent);
// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
return myImage;
}
- (void)saveGLScreenshotToPhotosAlbum {
UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil,
nil, nil);
}
http://blog.sina.com.cn/s/blog_4b55f6860101cc5x.html