Question

Say I have a main UIView which has several subviews of type CatView and DogView. I want to render this UIView as an image, but I want to exclude DogViews, so that the final rendered image has transparent pixels in place of any DogView. (Note that simply removing the DogViews from the view wouldn't work - I need transparent pixels where the DogViews were). Also the DogViews can be rotated so they don't necessarily take up rectangular portions of the view.

Any ideas on how I can approach this?

EDIT: First attempt

- (UIImage *)createCutOutViewFromView:(UIView*)view {

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextMoveToPoint(context, 200, 200);
    CGContextAddLineToPoint(context, 250, 200);
    CGContextAddLineToPoint(context, 250, 250);
    CGContextAddLineToPoint(context, 200, 250);
    CGContextClosePath(context);

    CGContextClip(context);

    [view.layer renderInContext:context];

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

    return result;

}

The result is that I can only see the 50px rectangle that I clipped. I actually want to see everything EXCEPT this rectangle. Any advice?

EDIT: 2nd attempt

- (UIImage *)createCutOutViewFromView:(UIView*)view {

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, view.bounds);

    [view.layer renderInContext:context];

    UIBezierPath* path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(200, 200)];
    [path addLineToPoint:CGPointMake(250, 200)];
    [path addLineToPoint:CGPointMake(250, 250)];
    [path addLineToPoint:CGPointMake(200, 250)];
    [path closePath];

    [path fillWithBlendMode:kCGBlendModeNormal alpha:0.0];


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


    return result;

}
Was it helpful?

Solution

Create a bitmapped graphics context and render the view into that context. Then for each DogView, create a UIBezierPath, and use moveToPoint, addLineToPoint, and closePath to draw an outline where the DogView would be. Then call fillWithBlendMode:alpha: with an alpha of 0.0 to clear that region of the drawing.

I like to use UIGraphicsBeginImageContext to create the bitmapped graphics context since it only needs a size, which you can get from the view's bounds. Here's the general framework.

UIGraphicsBeginImageContext( view.bounds.size );
CGContextRef context = UIGraphicsGetCurrentContext();

// drawing stuff goes here

UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top