问题描述
|
当我尝试使用此方法将OpenGL视图转换为UIImage时,仅返回视图的背景,而不返回GLView内容。如何将OpenGL的上下文转换为UIImage?
解决方法
使用下面的代码在
UIImage
中转换opengl
视图。
GLubyte *buffer = (GLubyte *) malloc(backingWidth * backingHeight * 4);
GLubyte *buffer2 = (GLubyte *) malloc(backingWidth * backingHeight * 4);
GLvoid *pixel_data = nil;
glReadPixels(0,backingWidth,backingHeight,GL_RGBA,GL_UNSIGNED_BYTE,(GLvoid *)buffer);
for (int y=0; y<backingHeight; y++) {
for (int x=0; x<backingWidth*4; x++) {
buffer2[y * 4 * backingWidth + x] =
buffer[(backingHeight - y - 1) * backingWidth * 4 + x];
}
}
CGDataProviderRef provider;
provider = CGDataProviderCreateWithData(NULL,buffer2,backingWidth * backingHeight * 4,freeImageData);
// set up for CGImage creation
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
// Use this to retain alpha
//CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(backingWidth,bitsPerComponent,bitsPerPixel,bytesPerRow,colorSpaceRef,bitmapInfo,provider,NULL,NO,renderingIntent);
// this contains our final image.
UIImage *newUIImage = [UIImage imageWithCGImage:imageRef];
摘自
, 这取决于您使用的OpenGL视图。从iOS 5开始,您可以使用GLKit和相应的GLKView来大大简化呈现UIImage的过程。
GLKView* v = (GLKView*) _previewViewController.view;
UIImage* thumbnail = [v snapshot];
http://developer.apple.com/library/ios/#documentation/GLkit/Reference/GLKView_ClassReference/Reference/Reference.html
, 感谢您的代码。我发现它很有用,但我不得不添加一些额外的代码以正确释放带有缓冲区,buffer2,imageRef,colorSpaceRef和提供程序指针的分配的内存。请注意,buffer2是使用提供程序释放功能释放的。
static void myProviderReleaseData (void *info,const void *data,size_t size)
{
free((void*)data);
}
- (UIImage*)renderToImage
{
// The image size should be grabbed from your ESRenderer class.
// That parameter is get in renderer function:
// - (BOOL) resizeFromLayer:(CAEAGLLayer *)layer {
// glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,GL_RENDERBUFFER_WIDTH_OES,&backingWidth);
GLint backingWidth = renderer.backingWidth;
GLint backingHeight = renderer.backingHeight;
GLubyte *buffer = (GLubyte *) malloc(backingWidth * backingHeight * 4);
GLubyte *buffer2 = (GLubyte *) malloc(backingWidth * backingHeight * 4);
glReadPixels(0,(GLvoid *)buffer);
for (int y=0; y<backingHeight; y++) {
for (int x=0; x<backingWidth*4; x++) {
buffer2[y * 4 * backingWidth + x] =
buffer[(backingHeight - y - 1) * backingWidth * 4 + x];
}
}
free(buffer);
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,myProviderReleaseData);
// set up for CGImage creation
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * backingWidth;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
// Use this to retain alpha
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(backingWidth,renderingIntent);
// this contains our final image.
UIImage *newUIImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
return newUIImage;
}