openGL ES view 截屏保存成UIImage

你的应用程序会发送一些openGLES 指令到当前的渲染环境(EAGLContext  object),EAGLContext 包含了一些你要渲染目标的一些状态信息。给你的openGL ES view 快照截屏,确保你已经当前的EAGLContext和framebuffer下,然后调用 glReadPixels 从framebuffer中获得像素数据。然后你就可以用这些像素数据创建一个CGImage,然后通过CGImage创建UIImage。

        iphone中的UIkit坐标系统(y轴下)是和openGL ES ,Quartz坐标系统(y轴上)相互颠倒的。当你从CGImage创建UIImage的时候要考虑到这种情况,防止创建的图片是颠倒的。下面我们将演示通过UIGraphic创建一个翻转的位图环境(bitmap context),然后把原图image渲染到上面。

重要的一点:你必须在调用EAGLContext / -presentRenderbuffer: 之前调用 glReaderPiexels 去获得结果,除非你用了一个已经被retain的后台缓冲。


默认情况下,当你把renderbuffer里的内容呈现到屏幕上后,renderbuffer里的内容就失效了。因此,要读取openGL ES 准确的内容,你必须按照一下做法的一种:

1)你必须在调用EAGLContext / -presentRenderbuffer: 之前调用 glReaderPiexels

2)设置的CAEAGLLayer的retain属性设置为true,保留该层的内容。但是,这可能有不良反应性能的影响,所以你注意,只在必要时使用此这种方法。

以上的限制是不能运用到屏幕以外,没有显示的framebuffer。


OpenGL ES view snapshot 截屏

// IMPORTANT: Call this method after you draw and before -presentRenderbuffer:.


- (UIImage*)snapshot:(UIView*)eaglview


{


    GLint backingWidth, backingHeight;


 


    // Bind the color renderbuffer used to render the OpenGL ES view


    // If your application only creates a single color renderbuffer which is already bound at this point,


    // this call is redundant, but it is needed if you're dealing with multiple renderbuffers.


    // Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class.


    glBindRenderbufferOES(GL_RENDERBUFFER_OES, _colorRenderbuffer);


 


    // Get the size of the backing CAEAGLLayer


    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);


    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);


 


    NSInteger x = 0, y = 0, width = backingWidth, height = backingHeight;


    NSInteger dataLength = width * height * 4;


    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte));


 


    // Read pixel data from the framebuffer


    glPixelStorei(GL_PACK_ALIGNMENT, 4);


    glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);


 


    // Create a CGImage with the pixel data


    // If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel


    // otherwise, use kCGImageAlphaPremultipliedLast


    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL);


    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();


    CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast,


                                    ref, NULL, true, kCGRenderingIntentDefault);


 


    // OpenGL ES measures data in PIXELS


    // Create a graphics context with the target size measured in POINTS


    NSInteger widthInPoints, heightInPoints;


    if (NULL != UIGraphicsBeginImageContextWithOptions) {


        // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration


        // Set the scale parameter to your OpenGL ES view's contentScaleFactor


        // so that you get a high-resolution snapshot when its value is greater than 1.0


        CGFloat scale = eaglview.contentScaleFactor;


        widthInPoints = width / scale;


        heightInPoints = height / scale;


        UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);


    }


    else {


        // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext


        widthInPoints = width;


        heightInPoints = height;


        UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints));


    }


 


    CGContextRef cgcontext = UIGraphicsGetCurrentContext();


 


    // UIKit coordinate system is upside down to GL/Quartz coordinate system


    // Flip the CGImage by rendering it to the flipped bitmap context


    // The size of the destination area is measured in POINTS


    CGContextSetBlendMode(cgcontext, kCGBlendModeCopy);


    CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref);


 


    // Retrieve the UIImage from the current context


    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();


 


    UIGraphicsEndImageContext();


 


    // Clean up


    free(data);


    CFRelease(ref);


    CFRelease(colorspace);


    CGImageRelease(iref);


 


    return image;


}


版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/zsw-1993/archive/2012/10/19/4880763.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值