============================================================
博文原创,转载请声明出处
电子咖啡(原id蓝岩)
============================================================
上篇blog介绍了如何进行普通截图:IOS屏幕截图---普通截图
前面已经说过,使用普通方式截屏,不能能够截取Opengl渲染的View。就像我们远程登录了另一台windows电脑时候,能看到对方的桌面等,但对方的视频我们并不能看到。对于此类view,我们需要将opengl渲染的view,通过glReadPixels将其所有的像素读取到数组中,然后通过这些像素数据创建UIImage,详细代码如下。
在我们opengl view,实现下面方法
//In Your GL View
//convert opengl data to UIImage
-(UIImage *) glToUIImage {
CGSize viewSize=self.frame.size;
NSInteger myDataLength = viewSize.width * viewSize.height * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, viewSize.width, viewSize.height, 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 < viewSize.height; y++)
{
for(int x = 0; x < viewSize.width* 4; x++)
{
buffer2[(int)((viewSize.height-1 - y) * viewSize.width * 4 + x)] = buffer[(int)(y * 4 * viewSize.width + 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 * viewSize.width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// make the cgimage
CGImageRef imageRef = CGImageCreate(viewSize.width , viewSize.height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
return myImage;
}
另外,我在实现这段代码时候,一下代码得到的buffer依然为空。
glReadPixels(0, 0, viewSize.width, viewSize.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
google上解释说,这是ios6的问题。需要在CAEAGLLayer初始化时候设置一下属性kEAGLDrawablePropertyRetainedBacking 为YES。
如下
CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer;
eaglLayer.drawableProperties = @{
kEAGLDrawablePropertyRetainedBacking: [NSNumber numberWithBool:YES],
kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
};
ref:
Download an Image and Save it as PNG or JPEG in iPhone SDK ‹ ObjectGraph Blog
iphone - Why do I get 'No -renderInContext: method found' warning? - Stack Overflow
iphone - Programmatically take a screenshot combining OpenGL and UIKit elements - Stack Overflow
iPhone – saving OpenGL ES content to the Photo Album | BIT-101
opengl es - Why is glReadPixels() failing in this code in iOS 6.0? - Stack Overflow