如何捕获OpenGL视图作为UIImage?

时间:2011-06-12 11:07:42

标签: iphone opengl-es uiimage

当我尝试使用this method将OpenGL视图转换为UIImage时,仅返回视图的背景,而不返回GLView内容。如何将OpenGL的上下文转换为UIImage?

3 个答案:

答案 0 :(得分:8)

这取决于您使用的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

答案 1 :(得分:5)

使用以下代码转换opengl中的UIImage视图。

GLubyte *buffer = (GLubyte *) malloc(backingWidth * backingHeight * 4);
 GLubyte *buffer2 = (GLubyte *) malloc(backingWidth * backingHeight * 4);
 GLvoid *pixel_data = nil;
 glReadPixels(0, 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, backingHeight,
                                 bitsPerComponent, bitsPerPixel,
                                 bytesPerRow, colorSpaceRef,
                                 bitmapInfo, provider,
                                 NULL, NO,
                                 renderingIntent);
 // this contains our final image.
 UIImage *newUIImage = [UIImage imageWithCGImage:imageRef];

Taken from

答案 2 :(得分:3)

感谢您的代码。我发现它很有用但我必须添加一些额外的代码才能正确释放已分配的内存,包括buffer,buffer2,imageRef,colorSpaceRef和provider指针。请注意,缓冲区2随提供程序释放功能一起发布。

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, 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];
        }
    }
    free(buffer);
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2,
                                            backingWidth * backingHeight * 4,
                                        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, backingHeight,
                                        bitsPerComponent, bitsPerPixel,
                                    bytesPerRow, colorSpaceRef,
                                    bitmapInfo, provider,
                                    NULL, NO,
                                    renderingIntent);
    // this contains our final image.
    UIImage *newUIImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGColorSpaceRelease(colorSpaceRef);
    CGDataProviderRelease(provider);

    return newUIImage;
}