Как захватить представление OpenGL как UIImage? - PullRequest
4 голосов
/ 12 июня 2011

Когда я пытаюсь использовать этот метод для преобразования представления OpenGL в UIImage, возвращается только фон представления, но не содержимое GLView. Как я могу преобразовать контекст OpenGL в UIImage?

Ответы [ 3 ]

8 голосов
/ 15 января 2013

Это зависит от того, какой вид 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

5 голосов
/ 12 июня 2011

Используйте приведенный ниже код для преобразования вашего 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];

Взято из

3 голосов
/ 24 августа 2011

Спасибо за код. Я считаю это полезным, но мне пришлось добавить дополнительный код, чтобы правильно освободить выделенную память с буфером, 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, 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;
}   
...