How to align a mask onto an image

2019-08-07 08:17发布

问题:

I'm writing in Swift, trying to mask an image using UIImage and CALayer. The problem is that the mask is scaled and shifted when applied to the image. I have created my UIImageViewer using the Interface Builder and I have set it to Aspect Fit. I would like to mask images of arbitrary size. I generate the mask image to be the same size as the image. This is a requirement because later I want to add more elements to my mask programmatically and it has to cover the masked image. Here's my code:

class ViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    var img = UIImage(named: "flowers.png")

    var maskImageSize = CGSizeMake(img!.size.width, img!.size.height)

    UIGraphicsBeginImageContextWithOptions(maskImageSize, false, 0.0)

    var color = UIColor(white: 1.0, alpha: 0.0)
    color.setFill()
    var rect = CGRectMake(0, 0, img!.size.width, img!.size.height)
    UIRectFill(rect)

    color = UIColor(white: 0.0, alpha: 1.0)
    color.setFill()
    rect = CGRectMake((img!.size.width/2)-50, (img!.size.height/2)-50, 100, 100)
    UIRectFill(rect)

    var maskImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    var maskLayer = CALayer()
    maskLayer.frame = self.imageView.layer.bounds // it'll have the same problem if I set it to self.imageView.layer.frame
    maskLayer.contents = maskImage.CGImage
    maskLayer.contentsGravity = kCAGravityCenter

    self.imageView.image = img
    self.imageView.layer.mask = maskLayer;
    self.imageView.layer.masksToBounds = true
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

I need to know how to align the image mask onto the original image. Thanks for your help!

I have pretty good screen shots but Stackoverflow doesn't let me to post them because I don't have enough reputation!

回答1:

The problem here is that if you use aspect fit then the size of the image as displayed depends upon both the size of the original image and the size of the image view. What you are trying to do is to imitate what the image view does to the image - and you have no way of knowing exactly what that is.

The best you can do is guess. What you are looking for is the size of the largest rectangle that will fit into your image view's bounds while keeping the aspect ratio of the original image. It happens that if you import the AV Foundation framework, there's a handy function that gives you that information, AVMakeRectWithAspectRatioInsideRect (documented here: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVFoundation_Functions/index.html#//apple_ref/c/func/AVMakeRectWithAspectRatioInsideRect).



回答2:

I faced the same problem too, and i fixed it in the utilities of the UIImageView. in the drawing section i just check the clip Subview like this

and the problem is fixed!