Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone - flattening a UIImageView and subviews to image = blank image

Tags:

iphone

I have a UIImageView with zillions of views. Some of these views have layer shadows or glow. This view is slightly bigger than the device screen.

This view is basically a big transparent view that contains many objects (images, buttons, etc.)

Now I want to flatten everything on that view to a UIImage. Then, I do:

UIGraphicsBeginImageContext( [viewWithZillionsOfObjects bounds].size );
[[viewWithZillionsOfObjects layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

result is equal to a totally transparent image, but has the correct size.

am I missing something?

thanks

like image 790
Duck Avatar asked Oct 06 '10 05:10

Duck


1 Answers

In Apple's sample code, they adjust the geometry of the graphics context to match the geometry of the layer before calling renderInContext:.

They're dealing with a window, but it looks like the code should work with any view with some minor changes.

I've not tried building this, but here's my attempt to change Apple's code to work on any view.

- (UIImage*)imageFromView:(UIView *)view 
{
    // Create a graphics context with the target size
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
    CGSize imageSize = [view bounds].size;
    if (NULL != UIGraphicsBeginImageContextWithOptions)
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    else
        UIGraphicsBeginImageContext(imageSize);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // -renderInContext: renders in the coordinate space of the layer,
    // so we must first apply the layer's geometry to the graphics context
    CGContextSaveGState(context);
    // Center the context around the view's anchor point
    CGContextTranslateCTM(context, [view center].x, [view center].y);
    // Apply the view's transform about the anchor point
    CGContextConcatCTM(context, [view transform]);
    // Offset by the portion of the bounds left of and above the anchor point
    CGContextTranslateCTM(context,
                          -[view bounds].size.width * [[view layer] anchorPoint].x,
                          -[view bounds].size.height * [[view layer] anchorPoint].y);

    // Render the layer hierarchy to the current context
    [[view layer] renderInContext:context];

    // Restore the context
    CGContextRestoreGState(context);

    // Retrieve the screenshot image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;
}
like image 120
Kris Markel Avatar answered Sep 28 '22 00:09

Kris Markel