user754905
user754905

Reputation: 1809

UIImage border around mask

I am currently this code to create a mask on my image.

- (UIImage*) maskImage:(UIImage *) image withMask:(UIImage *) mask
{
    CGImageRef imageReference = image.CGImage;
    CGImageRef maskReference = mask.CGImage;

    CGImageRef imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
                                             CGImageGetHeight(maskReference),
                                             CGImageGetBitsPerComponent(maskReference),
                                             CGImageGetBitsPerPixel(maskReference),
                                             CGImageGetBytesPerRow(maskReference),
                                             CGImageGetDataProvider(maskReference),
                                             NULL, // Decode is null
                                             YES // Should interpolate
                                             );

    CGImageRef maskedReference = CGImageCreateWithMask(imageReference, imageMask);
    CGImageRelease(imageMask);

    UIImage *maskedImage = [UIImage imageWithCGImage:maskedReference];
    CGImageRelease(maskedReference);

    return maskedImage;
}

I now want to add a 2 point border around the masked output (Like in the source url). Any ideas how I can accomplish this?

Thanks!

Upvotes: 2

Views: 2419

Answers (2)

Pooja M. Bohora
Pooja M. Bohora

Reputation: 1331

Please refer to the below link, I also wanted to achieve the same.

Applying border to image shape

Please find code below:

- (UIImage*)mergeImage:(UIImage*)first withImage:(UIImage*)second
{
    // get size of the second image
    CGImageRef secondImageRef = second.CGImage;
    CGFloat secondWidth = CGImageGetWidth(secondImageRef);
    CGFloat secondHeight = CGImageGetHeight(secondImageRef);

    float offsetwt,offsetht,offset;

    offset=20;
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    {
        offset=offset/2;
    }
    offsetht=(secondHeight   * (secondWidth+offset)) /secondWidth;
    offsetwt=secondWidth+offset;

    // build merged size
    CGSize mergedSize = CGSizeMake(offsetwt,offsetht);

    // capture image context ref
    UIGraphicsBeginImageContext(mergedSize);

    //Draw images onto the context
    [first drawInRect:CGRectMake(0, 0, offsetwt, offsetht)];
    [second drawInRect:CGRectMake(offset/2, offset/2, secondWidth, secondHeight) blendMode:kCGBlendModeNormal alpha:1.0];

    // assign context to new UIImage
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    // end context
    UIGraphicsEndImageContext();

    return  newImage;
}

Where first parameter the image you use for masking and second is the masked image. You may set offset as per your requirement. I hope this helps you.

Upvotes: 0

Rob
Rob

Reputation: 437422

At least two options:

  1. Have three images, the image that will be revealed inside, the image that will be used to mask that first image, and then a third image that is the border (this latter image will have a transparent center). You can then mask the first image with the second, and then overlay the image with just the border on top of the masked image.

    But it's not easy to generate a border programmatically of an irregular shaped image. It might be easier to use a graphical editor tool (like PhotoShop or whatever) to create an image that will be used for the border.

  2. Rather than masking with an image, you can often create a UIBezierPath for the mask, and from that path, you'll create two CAShapeLayer objects, one which you'll use to mask your image view and one that you'll use to add the border:

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path addArcWithCenter:CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0) radius:self.view.bounds.size.width * 0.4 startAngle:0 endAngle:M_PI * 2.0  clockwise:YES];
    
    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.path = path.CGPath;
    mask.fillColor = [[UIColor blackColor] CGColor];
    self.imageView.layer.mask = mask;
    
    CAShapeLayer *border = [CAShapeLayer layer];
    border.path = path.CGPath;
    border.strokeColor = [[UIColor blueColor] CGColor];
    border.fillColor = [[UIColor clearColor] CGColor];
    border.lineWidth = 10.0;
    [self.imageView.layer addSublayer:border]
    

    That's an example where the path is a simple circle, but you can create a heart shaped path or whatever. Bezier paths take a while to get used to, but they're powerful for drawing smooth curved shapes.

Bottom line, if the border has some regular shape that I can generate with bezier curves, I prefer the second approach. If the border is something that I'll draw manually in my image editing tool, then I'd use the first approach.

Upvotes: 2

Related Questions