Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create reverse masks on CALayers

I'll make this as simple as possible.

How do I create reverse masks on CALayers in iOS?

I have a red view and an image that is used to mask the red view. enter image description here

I use the view's CALayer's mask property to apply the mask, the result is the following. enter image description here

However what I desire would be the opposite result, such as (imagine that the white part here is actually the wood in the background, because I am not very good with image editing software) enter image description here

To put in other words: I want the masking image to punch a hole through the view, and not act as an actual masking layer. Answers in both C# (MonoTouch) or Obj-C are fine either way

like image 470
Louis Boux Avatar asked Nov 16 '11 16:11

Louis Boux


2 Answers

Hope it is helpful

Step 1: Create a mask without any alpha channel.

Step 2: Create a invert mask by following method

- (UIImage*)createInvertMask:(UIImage *)maskImage withTargetImage:(UIImage *) image {

    CGImageRef maskRef = maskImage.CGImage;

    CGBitmapInfo bitmapInfo = kCGImageAlphaNone;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

    CGImageRef mask = CGImageCreate(CGImageGetWidth(maskRef),
                                    CGImageGetHeight(maskRef),
                                    CGImageGetBitsPerComponent(maskRef),
                                    CGImageGetBitsPerPixel(maskRef),
                                    CGImageGetBytesPerRow(maskRef),
                                    CGColorSpaceCreateDeviceGray(),
                                    bitmapInfo,
                                    CGImageGetDataProvider(maskRef),
                                    nil, 
                                    NO, 
                                    renderingIntent);


    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);

    CGImageRelease(mask);
    CGImageRelease(maskRef);

    return [UIImage imageWithCGImage:masked];
}

Step 3: Set the invert mask to a UIView by following method

- (void)maskWithImage:(UIImage*) maskImage TargetView:(UIView*) targetView {
    CALayer *_maskingLayer = [CALayer layer];
    _maskingLayer.frame = targetView.bounds;
    [_maskingLayer setContents:(id)[maskImage CGImage]];
    [targetView.layer setMask:_maskingLayer];
}

Finished.

How to call?

UIImage* targetImage = [UIImage imageNamed:@"sky_bg.png"];
UIImage* mask = [UIImage imageNamed:@"mask01.png"];

UIImage* invertMask = [self createInvertMask:mask withTargetImage:targetImage];

[self maskWithImage:invertMask TargetView:targetview];
like image 174
Gary Avatar answered Oct 18 '22 18:10

Gary


You need to reverse the alpha of your mask, so the "holes" are the transparent pixels. You'll also want to stretch your image to cover the whole red view.

like image 24
Mike Katz Avatar answered Oct 18 '22 18:10

Mike Katz