如何在cocos2d中截屏



如何在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);


http://hi.baidu.com/diguo2046/item/510e462d6e8a780e42634ace

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章