Can we set below shape on image with UIImageView
.
Any idea!
Thanks
Sorry for hardcode. Try to use UIBezierPath
to set any shape you want.
CAShapeLayer* maskLayer = [CAShapeLayer layer];
UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(75, 200)];
[path addCurveToPoint:CGPointMake(0, 100) controlPoint1:CGPointMake(0, 150) controlPoint2:CGPointMake(0, 150)];
[path addArcWithCenter:CGPointMake(75, 100) radius:75 startAngle:M_PI endAngle:0 clockwise:YES];
[path addCurveToPoint:CGPointMake(75, 200) controlPoint1:CGPointMake(150, 150) controlPoint2:CGPointMake(150, 150)];
[path closePath];
maskLayer.backgroundColor = [[UIColor clearColor] CGColor];
maskLayer.path = [path CGPath];
yourImageView.layer.mask = maskLayer;
It's easy by using
UIImageView *image=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"balloon_selected_left.png"] ];
self.maskImage.layer.mask=image.layer;
UIImageView
You can use mask
property of imageView's CALayer:
CALayer *mask = [CALayer layer];
mask.contents = (id)[[UIImage imageNamed:@"mask.png"] CGImage];
mask.frame = CGRectMake(0, 0, imageView.image.size.width, imageView.image.size.height);
imageView.layer.mask = mask;
imageView.layer.masksToBounds = YES;
UIImage
This will apply to ImageView only, so if you want to change UIImage directly - you should use Core Graphics mask:
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask);
UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
CGImageRelease(mask);
CGImageRelease(maskedImageRef);
// returns new image with mask applied
return maskedImage;
}
Swift 5.
let image = UIImage(named: "Lenna.png")!
let mask = UIImage(named: "mask-image.png")! // background is transparent
let size = image.size
let renderer = UIGraphicsImageRenderer(size: size)
let newImage = renderer.image { context in
image.draw(in: CGRect(origin: .zero, size: size), blendMode: .normal, alpha: 1)
mask.draw(in: CGRect(origin: .zero, size: size), blendMode: .destinationIn, alpha: 1)
}
Playground:
Like others suggest, I would use the image's mask
property.
Info from Apple about the mask
property:
The layer’s alpha channel determines how much of the layer’s content and background shows through. Fully or partially opaque pixels allow the underlying content to show through but fully transparent pixels block that content. The default value of this property is nil nil.
When configuring a mask, remember to set the size and position of the mask layer to ensure it is aligned properly with the layer it masks.
That last sentence is important!
I used Sketch to create a black image with a transparent background (PNG).
Add it to your Assets.xcassets folder. My image is called profileMask
.
Create an outlet for the image view. I called mine profileImageView
.
override func viewDidLoad() {
super.viewDidLoad()
let maskImageView = UIImageView()
maskImageView.contentMode = .scaleAspectFit
maskImageView.image = #imageLiteral(resourceName: "profileMask")
maskImageView.frame = profileImageView.bounds
profileImageView.mask = maskImageView
}
Note:
Here is what it looks like when run:
Guys, this was a pain to do. I tried to create a Bezier Path but to be honest my skills on making an exact shape to match the mask was impossible for me. A Bezier Path would probably look really good if you have the skills to do that but I don't. :(
So I had the idea, "What if I just use the mask image as the border?" It worked! The benefit of doing it this way is you can use ANY mask shape in the future and it will create a border for it without having to figure out the bezier path.
Here's how I did it:
profileImageView
to the mask and change the tint color to whatever I want the border to be.profileImageView
minus 2 points (to show the underlying mask image which will be the border).profileImageView
.Here's the code in viewDidLoad now:
override func viewDidLoad() {
super.viewDidLoad()
// Add border first (mask image)
profileImageView.contentMode = .scaleAspectFit
profileImageView.tintColor = .lightGray // Border Color
profileImageView.image = #imageLiteral(resourceName: "profileMask")
// Profile Image
let profileImage = UIImageView()
profileImage.image = #imageLiteral(resourceName: "Profile")
profileImage.contentMode = .scaleAspectFill
// Make a little bit smaller to show "border" image behind it
profileImage.frame = profileImageView.bounds.insetBy(dx: 2, dy: 2)
// Mask Image
let maskImageView = UIImageView()
maskImageView.image = #imageLiteral(resourceName: "profileMask")
maskImageView.contentMode = .scaleAspectFit
maskImageView.frame = profileImage.bounds
// Apply mask to profile iamge
profileImage.mask = maskImageView
// Add profile image as a subview on top of the "border" image
profileImageView.addSubview(profileImage)
}
So now it looks like this when we run it:
What could be really cool is if we create a custom UIImageView with a mask and border width property. Then you can just assign these properties and the custom class will take care of the rest. Let me know if you guys want to see something like this and I'll create it and post it here. Maybe also make a YouTube video tutorial for my channel.
Yes, you can set a shape on UIImage. First, add a Mask image(which shape you want) in your project. and write these code.
[yourImageView setImage:[self createMaskImage:yourImage withMask:MaskImage]];
- (UIImage*) createMaskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
return [UIImage imageWithCGImage:masked];
}