sree_iphonedev
sree_iphonedev

Reputation: 3534

Circle masking for image cropping in ios

I am trying to give a circular mask to image view and I have to crop the image portion in circular area, which is working fine. But I am facing some problem with the mask, which is annotated in the attached image.Masking an image for cropping feature

Following are pieces of code which I have used to mask.

Adding mask to image view layer

CAShapeLayer *maskLayer = [CAShapeLayer layer];
self.imageView.layer.mask = maskLayer;
self.maskLayer = maskLayer;

create shape layer for circle we'll draw on top of image (the boundary of the circle)

CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.lineWidth = 3.0;
circleLayer.fillColor = [[UIColor clearColor] CGColor];
circleLayer.strokeColor = [[UIColor blackColor] CGColor];
[self.imageView.layer addSublayer:circleLayer];
self.circleLayer = circleLayer;

create circle path

[self updateCirclePathAtLocation:CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0) radius:self.view.bounds.size.width * 0.30];

- (void)updateCirclePathAtLocation:(CGPoint)location radius:(CGFloat)radius
{
    self.circleCenter = location;
    self.circleRadius = radius;

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path addArcWithCenter:self.circleCenter
                    radius:self.circleRadius
                startAngle:0.0
                  endAngle:M_PI * 2.0
                 clockwise:YES];

    /*
    [[UIColor colorWithWhite:0 alpha:0.1] setFill];
    [path fill];
    */

    self.maskLayer.path = [path CGPath];
    self.circleLayer.path = [path CGPath];
}

Can anyone give a suggestion to make the white area around the circular mask to be partially visible or apply transparent CGColor using alpha?

Upvotes: 0

Views: 2026

Answers (1)

Teja Nandamuri
Teja Nandamuri

Reputation: 11201

The way I did is:

I placed a UIView on top of UIImageView, and I made a transparent hole in the top UIView, so that bottom image can be seen through that view.

Here is the drawRect of the UIView:

- (void)drawRect:(CGRect)rect { 
    [super drawRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    // Clear any existing drawing on this view
    // Remove this if the hole never changes on redraws of the UIView
    CGContextClearRect(context, self.bounds);

    // Create a path around the entire view
    UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:self.bounds];

    // Your transparent window. This is for reference, but set this either as a property of the class or some other way
    CGRect transparentFrame; //this is the frame of the hole
    // Add the transparent window
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:transparentFrame cornerRadius:5.0f];
    [clipPath appendPath:path];

    // NOTE: If you want to add more holes, simply create another UIBezierPath and call [clipPath appendPath:anotherPath];

    // This sets the algorithm used to determine what gets filled and what doesn't
    clipPath.usesEvenOddFillRule = YES;
    // Add the clipping to the graphics context
    [clipPath addClip];

    // set your color
    UIColor *tintColor = [UIColor greenColor]; 

    // (optional) set transparency alpha
    CGContextSetAlpha(context, 0.7f);
    // tell the color to be a fill color
    [tintColor setFill];
    // fill the path
    [clipPath fill];
}

Here I have used the bezierWithROundedRect and you can use bezierWIthArc to get the circular bezier.

You will get something like this:

enter image description here

You can adjust the alpha of topView to get the desired transparency. By this way, you can also move the hole by touch and the view gets redrawn based on your touch location.

Upvotes: 2

Related Questions