I'm trying to darken the surrounding area of my UIImageView, and leave a portion alone (which I define with my mask).
Right now I'm defining my mask and setting my imageView.layer.mask, however instead of darkening the rest of the image, it's completely removing it instead.
Example of the type of effect I want:
Example of what I'm getting:
The reference docs mention that the mask uses it's layer's alpha, so I've tried manipulating the mask's opacity. However, that only seems to affect the opacity of the portion I want to leave alone, while the rest of the image is still being cut out completely.
Can anyone point out what I'm doing wrong? Thanks.
Here's my code:
CAShapeLayer *mask = [CAShapeLayer layer];
GMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 1052, 448);
CGPathAddLineToPoint(path, nil, 2, 484);
CGPathAddLineToPoint(path, nil, 54, 1263);
CGPathAddLineToPoint(path, nil, 56, 1305);
CGPathAddLineToPoint(path, nil, 380, 1304);
CGPathAddLineToPoint(path, nil, 1050, 1311);
CGPathCloseSubpath(path);
mask.path = path;
CGPathRelease(path);
//mask.opacity = 0.5; //doesn't affect the surrounding portion, only the cut out area.
self.imageView.layer.mask = mask;
What you're doing wrong is using a layer mask in the first place. You are trying to shade or darken an area of your image. That's not what a layer mask does at all! Basically a layer mask punches through in an existing layer, causing whatever is behind it to show through. That's exactly what you discovered:
it's completely removing it instead
Yes, because that's what layer masks do! If you don't want that, why are you using a layer mask?
What you want is just to lay a second image view (or just a sublayer) over the first one. It contains an image that you draw. It is transparent except where it has a semi-transparent dark color fill. That will darken what's behind it. You use a clipping path to define the area that doesn't get the dark color fill.
Alternatively, alter the image in your image view by drawing on top of it with compositing or possibly using a CIFilter.
In case anyone else has the same issue: if the goal is to darken the layer, the mask is not suitable. But if you need to make a part of the image transparent or semi-transparent, it is definitely a great way to go.
For example, this code could live in an NSView subclass:
let imageLayer = CALayer()
let maskLayer = CAShapeLayer()
let ovalPath = NSBezierPath(ovalIn: bounds)
maskLayer.path = ovalPath
maskLayer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
maskLayer.frame = bounds
maskLayer.backgroundColor = NSColor.black.withAlphaComponent(0.2).cgColor
imageLayer.contents = NSImage(named: "sampleImage")
imageLayer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
imageLayer.frame = bounds
imageLayer.mask = maskLayer
This gives 0.2 opacity to an oval 'hole' in the imageLayer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With