【问题标题】:Xcode Screenshot EAGLContext [duplicate]Xcode Screenshot EAGLContext [重复]
【发布时间】:2012-06-17 16:11:17
【问题描述】:

可能重复:
How to get UIImage from EAGLView?

所以我只是想知道是否有人知道任何方法可以将存储在 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;

我正在使用 OpenGLES 1 绘制到 UIView 上的 EAGLContext 属性(技术上是视图控制器上另一个 UIView 上的 UIView 上的 EAGLContext,但我认为这不应该有任何区别)。

如果有人知道这件事,即使只是我完全在吠叫一棵不可能的树,请告诉我!

马特

【问题讨论】:

    标签: objective-c xcode uiimage screenshot eaglcontext


    【解决方案1】:

    几天后,我终于找到了一个可行的解决方案。 Apple 提供了从 EAGLView 生成 UIImage 的代码。然后你只需要垂直翻转图像,因为 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;
    }
    

    【讨论】:

    • 这是在操作系统为 6 的设备上工作吗?
    • 尚未测试它,因为我不再从事该项目。虽然我无法想象为什么它不起作用,但我不认为他们用 iOS 6 改变了 gl 的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 2014-05-05
    • 1970-01-01
    相关资源
    最近更新 更多