============================================================博文原創,轉載請聲明出處電子咖啡(原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