之前写过一个常规的屏幕截图:http://blog.csdn.net/hitwhylz/article/details/17189351
但是发现这个办法对于OpenGL 无用。 获取到的数据为空。
所以这里介绍下OpenGL ES屏幕截图。
1.初始化。
CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer; eaglLayer.drawableProperties = @{ kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES], kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8 };
2.声明方法。
- (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 "viewRenderbuffer" with the actual name of the renderbuffer object defined in your class. glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); // 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; }
3.使用
调用上述的方法即可。
- (UIImage*)snapshot:(UIView*)eaglview