2012-06-14 3 views
1

Можно создать дубликат:
How to get UIImage from EAGLView?Xcode Скриншот EAGLContext

Так что я был просто интересно, если кто-нибудь знает какой-либо способ, чтобы сохранить то, что хранится в EAGLContext как UIImage.

настоящее время я использую:

UIGraphicsBeginImageContext(CGSizeMake(768, 1024)); 
[self.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

в других приложениях у меня есть, и это работает отлично, но, очевидно, EAGLContext не обладает свойством .layer. Я пробовал литье в UIView, но это - не удивительно - не работает:

UIView *newView = [[UIView alloc] init]; 
newView = (UIView *)context; 

Я рисую к собственности EAGLContext на UIView (технически это EAGLContext на UIView на другой UIView на View Controller, но я полагаю, что это не должно иметь никакого значения) с использованием OpenGLES 1.

Если кто-нибудь знает об этом, даже если это просто, что я полностью лаем невозможное дерево, пожалуйста, дайте мне знать!

Matt

ответ

3

Через несколько дней я, наконец, получил рабочее решение этой проблемы. Существует код, предоставленный Apple, который создает UIImage из EAGLView. Затем вам просто нужно перевернуть изображение по вертикали, так как UIKit перевернут. Ссылка на документацию, где я нашел этот метод, больше не существует.

Метод захвата EAGLView:

-(UIImage *)drawableToCGImage 
{ 
    GLint backingWidth2, backingHeight2; 
    //Bind the color renderbuffer used to render the OpenGL ES view 
    // If your application only creates a single color renderbuffer which is already bound at this point, 
    // this call is redundant, but it is needed if you're dealing with multiple renderbuffers. 
    // Note, replace "_colorRenderbuffer" with the actual name of the renderbuffer object defined in your class. 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 

    // Get the size of the backing CAEAGLLayer 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth2); 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight2); 

    NSInteger x = 0, y = 0, width2 = backingWidth2, height2 = backingHeight2; 
    NSInteger dataLength = width2 * height2 * 4; 
    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); 

    // Read pixel data from the framebuffer 
    glPixelStorei(GL_PACK_ALIGNMENT, 4); 
    glReadPixels(x, y, width2, height2, GL_RGBA, GL_UNSIGNED_BYTE, data); 

    // Create a CGImage with the pixel data 
    // If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel 
    // otherwise, use kCGImageAlphaPremultipliedLast 
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
    CGImageRef iref = CGImageCreate(width2, height2, 8, 32, width2 * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, 
            ref, NULL, true, kCGRenderingIntentDefault); 

    // OpenGL ES measures data in PIXELS 
    // Create a graphics context with the target size measured in POINTS 
    NSInteger widthInPoints, heightInPoints; 
    if (NULL != UIGraphicsBeginImageContextWithOptions) { 
     // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration 
     // Set the scale parameter to your OpenGL ES view's contentScaleFactor 
     // so that you get a high-resolution snapshot when its value is greater than 1.0 
     CGFloat scale = self.contentScaleFactor; 
     widthInPoints = width2/scale; 
     heightInPoints = height2/scale; 
     UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale); 
    } 
    else { 
     // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext 
     widthInPoints = width2; 
     heightInPoints = height2; 
     UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints)); 
    } 

    CGContextRef cgcontext = UIGraphicsGetCurrentContext(); 

    // UIKit coordinate system is upside down to GL/Quartz coordinate system 
    // Flip the CGImage by rendering it to the flipped bitmap context 
    // The size of the destination area is measured in POINTS 
    CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); 
    CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref); 

    // Retrieve the UIImage from the current context 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    // Clean up 
    free(data); 
    CFRelease(ref); 
    CFRelease(colorspace); 
    CGImageRelease(iref); 

    return image; 
} 

метод, чтобы перевернуть изображение по вертикали:

- (UIImage *)flipImageVertically:(UIImage *)originalImage 
{ 
    UIImageView *tempImageView = [[UIImageView alloc] initWithImage:originalImage]; 
    UIGraphicsBeginImageContext(tempImageView.frame.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGAffineTransform flipVertical = CGAffineTransformMake(
                  1, 0, 0, -1, 0, tempImageView.frame.size.height 
                  ); 
    CGContextConcatCTM(context, flipVertical); 

    [tempImageView.layer renderInContext:context]; 

    UIImage *flippedImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    //[tempImageView release]; 

    return flippedImage; 
} 
+0

Это один работает в устройстве, имеющем ОС как 6? – Dee

+0

Не тестировали, так как я больше не работаю над этим проектом. Хотя я не могу себе представить, почему это не сработает, я не думаю, что они изменили работу с iOS 6 –

Смежные вопросы