我有一个UIView
,在特定点上具有一定半径的透明maskLayer
。除此之外,我还有一个UIImageView
和UIPanGesture
的{{1}}。
现在,我可以拖动或缩放UIPinchGesture
,使其适合UIImageView
遮罩的一部分。完成后,我需要从UIView
那里获得UIImage
的透明部分。
我不知道该怎么实现。
以下是在UIImageView
上使用指定的遮罩UIView
和半径创建覆盖的代码。
CGRect
如有需要,我在这里存储func createOverlay(frame: CGRect,
xOffset: CGFloat,
yOffset: CGFloat,
radius: CGFloat) -> UIView {
// Step 1
let overlayView = UIView(frame: frame)
overlayView.backgroundColor = UIColor.groupTableViewBackground.withAlphaComponent(0.8)
// Step 2
let path = CGMutablePath()
beizerPath = UIBezierPath(arcCenter: CGPoint(x: xOffset, y: yOffset + radius), radius: radius, startAngle: 0.0, endAngle: 2.0 * .pi, clockwise: false)
path.addArc(center: CGPoint(x: xOffset, y: yOffset),
radius: radius,
startAngle: 0.0,
endAngle: 2.0 * .pi,
clockwise: false)
path.addRect(CGRect(origin: .zero, size: overlayView.frame.size))
// Step 3
let maskLayer = CAShapeLayer()
maskLayer.backgroundColor = UIColor.black.cgColor
maskLayer.path = path
maskLayer.fillRule = .evenOdd
// Step 4
overlayView.layer.mask = maskLayer
overlayView.clipsToBounds = true
return overlayView
}
!
然后,我尝试将UIBezierPath
剪切到UIBezierPath
上,但这是rect的问题。因为UIImage
可以被拖动和缩放,所以它可以UIImageView
进行更改。下面是我用来创建剪辑的代码。
CGRect
其他解决方案,我考虑拍摄完整视图的快照,然后从中删除extension UIImage {
func imageByApplyingClippingBezierPath(_ path: UIBezierPath) -> UIImage {
// Mask image using path
let maskedImage = imageByApplyingMaskingBezierPath(path)
// Crop image to frame of path
let croppedImage = UIImage(cgImage: maskedImage.cgImage!.cropping(to: path.bounds)!)
return croppedImage
}
func imageByApplyingMaskingBezierPath(_ path: UIBezierPath) -> UIImage {
// Define graphic context (canvas) to paint on
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
// Set the clipping mask
path.addClip()
draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let maskedImage = UIGraphicsGetImageFromCurrentImageContext()!
// Restore previous drawing context
context.restoreGState()
UIGraphicsEndImageContext()
return maskedImage
}
}
。但是我不认为这是这样做的正确方法!
答案 0 :(得分:1)
如果可能的话,最简单的方法是创建圆形视图并创建该视图的快照。检查以下解决方案:
func cutImageCircle(_ image: UIImage?, inFrame imageFrame: CGRect, contentMode: UIView.ContentMode = .scaleAspectFill, circle: (center: CGPoint, radius: CGFloat)) -> UIImage? {
guard let image = image else { return nil }
func generateSnapshotImage(ofView view: UIView, scale: CGFloat = 0.0) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, scale)
defer { UIGraphicsEndImageContext() }
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
return UIGraphicsGetImageFromCurrentImageContext()
}
let imageViewPanel = UIView(frame: CGRect(x: 0.0, y: 0.0, width: circle.radius*2.0, height: circle.radius*2.0))
imageViewPanel.clipsToBounds = true
imageViewPanel.layer.cornerRadius = circle.radius
let imageView = UIImageView(frame: {
var frame = imageFrame
frame.origin.x -= circle.center.x-circle.radius
frame.origin.y -= circle.center.y-circle.radius
return frame
}())
imageView.contentMode = contentMode
imageView.image = image
imageViewPanel.addSubview(imageView)
let cutImage = generateSnapshotImage(ofView: imageViewPanel, scale: 1.0)
return cutImage
}
您只需要计算圆心在哪里以及它的大小。我在其中添加了调整帧的选项,因此您可以控制输出图像的大小。这样,您可以提高所拍摄图像的质量。