我怎样才能削减' UIImage中的透明孔?

时间:2014-05-04 03:04:51

标签: iphone objective-c cocoa-touch uiimage

我正在尝试在UIImage中剪切一个透明的方块,但老实说我不得不知道在哪里/如何开始。

非常感谢任何帮助。

谢谢!

3 个答案:

答案 0 :(得分:17)

假设您的图像正在视图中显示 - 可能是UIImageView。然后我们可以通过屏蔽视图层在该视图中打一个矩形孔。每个视图都有一个图层。我们将在该视图的图层中应用一个蒙版,它本身就是一个包含图像的图层,我们将在代码中生成该图层。除了中间某处的清晰矩形外,图像将为黑色。那个清晰的矩形将导致图像视图中的孔。

所以,让self.iv成为这个UIImageView。尝试运行此代码:

CGRect r = self.iv.bounds;
CGRect r2 = CGRectMake(20,20,40,40); // adjust this as desired!
UIGraphicsBeginImageContextWithOptions(r.size, NO, 0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextAddRect(c, r2);
CGContextAddRect(c, r);
CGContextEOClip(c);
CGContextSetFillColorWithColor(c, [UIColor blackColor].CGColor);
CGContextFillRect(c, r);
UIImage* maskim = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CALayer* mask = [CALayer layer];
mask.frame = r;
mask.contents = (id)maskim.CGImage;
self.iv.layer.mask = mask;

例如,在此图像中,白色方块不是叠加的正方形,而是一个洞,显示其背后的窗口背景的白色:

enter image description here

编辑:我感到有义务,因为我在评论中提到它,以展示如何使用CAShapeLayer做同样的事情。结果完全相同:

CGRect r = self.iv.bounds;
CGRect r2 = CGRectMake(20,20,40,40); // adjust this as desired!
CAShapeLayer* lay = [CAShapeLayer layer];
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, nil, r2);
CGPathAddRect(path, nil, r);
lay.path = path;
CGPathRelease(path);
lay.fillRule = kCAFillRuleEvenOdd;
self.iv.layer.mask = lay;

答案 1 :(得分:9)

这是一个简单的Swift函数cut#hole#inView,可以复制和粘贴2017

func cut(hole: CGRect, inView v: UIView) {
    let p:CGMutablePath = CGMutablePath()
    p.addRect(inView.bounds)
    p.addRect(hole)

    let s = CAShapeLayer()
    s.path = p
    s.fillRule = kCAFillRuleEvenOdd

    v.layer.mask = s
}

答案 2 :(得分:1)

只需要@Fattie的版本,再次感谢!这是Swift 5.1的更新代码:

private func cut(holeRect: CGRect, inView view: UIView) {
    let combinedPath = CGMutablePath()
    combinedPath.addRect(view.bounds)
    combinedPath.addRect(holeRect)

    let maskShape = CAShapeLayer()
    maskShape.path = combinedPath
    maskShape.fillRule = .evenOdd

    view.layer.mask = maskShape
}

如果您希望切口具有圆角,可以将combinedPath.addRect(holeRect)替换为rectanglePath.addRoundedRect(in: holeRect, cornerWidth: 8, cornerHeight: 8)