Programmatically take a screenshot combining OpenGL and UIKit elements

I was wondering if anyone could provide an example of how to take a screenshot that mixes OpenGL and UIKit elements. Ever since Apple released UIGetScreenImage()private, this has become a pretty tricky task because the two common methods that Apple used to replace include only UIKit or only OpenGL.

This similar question refers to Apple Technical Q & A QA1714 , but QA describes only how to process elements from the camera and UIKit. How are you going to visualize the hierarchy of the UIKit view in the context of the image, and then draw an image of your OpenGL ES view on top of it, as the answer to a similar question suggests?

+5
source share
1 answer

That should do the trick. Basically, turning everything into CG and creating an image, you can do everything with.

// In Your UI View Controller

- (UIImage *)createSavableImage:(UIImage *)plainGLImage
{    
    UIImageView *glImage = [[UIImageView alloc] initWithImage:[myGlView drawGlToImage]];
    glImage.transform = CGAffineTransformMakeScale(1, -1);

    UIGraphicsBeginImageContext(self.view.bounds.size);

    //order of getting the context depends on what should be rendered first.
    // this draws the UIKit on top of the gl image
    [glImage.layer renderInContext:UIGraphicsGetCurrentContext()];
    [someUIView.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Do something with resulting image 
    return finalImage;
}

// In Your GL View

- (UIImage *)drawGlToImage
{
    // Draw OpenGL data to an image context 

    UIGraphicsBeginImageContext(self.frame.size);

    unsigned char buffer[320 * 480 * 4];

    CGContextRef aContext = UIGraphicsGetCurrentContext();

    glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, &buffer);

    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, &buffer, 320 * 480 * 4, NULL);

    CGImageRef iref = CGImageCreate(320,480,8,32,320*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaLast, ref, NULL, true, kCGRenderingIntentDefault);

    CGContextScaleCTM(aContext, 1.0, -1.0);
    CGContextTranslateCTM(aContext, 0, -self.frame.size.height);

    UIImage *im = [[UIImage alloc] initWithCGImage:iref];

    UIGraphicsEndImageContext();

    return im;
}

Then, to create a screenshot

UIImage *glImage = [self drawGlToImage];
UIImage *screenshot = [self createSavableImage:glImage];
+4
source

All Articles