gpt4 book ai didi

ios - 有没有办法在 Swift 中使用 CAShapeLayer.compositingFilters 来合成蒙版?

转载 作者:行者123 更新时间:2023-12-01 22:46:01 25 4
gpt4 key购买 nike

我正在为 iPad 应用程序实现绘图功能。我在 CAShapeLayers 上使用 UIBezierPaths 进行绘图。通过为每个 TouchesBegan 事件创建一个新的 CAShapeLayer,我正在构建一个“堆叠”的 CAShapeLayer 数组,这使我能够通过在数组中弹出和推送层来轻松实现撤消和重做。我还通过使用一些 CAShapeLayer.compositingFilters 做了一些有趣的图层混合技术。这一切都运作良好。我的挑战是删除。

我正在尝试创建第二个 CAShapeLayers 数组并使用它们来掩盖第一组。我可以使用上面相同的技术添加到蒙版组,同时使用不透明颜色进行绘制,但我无法从蒙版组中删除不透明区域。

我认为我可以使用不透明的基础层(黑色、白色或其他)开始 mask 技术。然后,我希望使用 UIColor.clear.cgColor 绘制 UIBezierPaths,并将绘制的清晰路径与底层不透明的基础蒙版组合或合成。实际上,这应该“删除”蒙版的该区域,并隐藏我绘制到的堆叠的 CAShapeLayers。我不想将 mask 层组合到图像中,因为我将失去通过弹出和推送 mask 阵列轻松撤消和重做的能力。

我在下面添加了一些伪代码。任何解决方案的指示、帮助或策略将不胜感激!我已经为此工作了好几个星期了,我真的很困惑。我找不到任何有关我为此努力的策略的信息。另外,如果我从一开始就错误地使用了绘图功能,并且有一种更简单的方法可以在保持简单的撤消/重做和添加删除的同时进行绘图,请告诉我。我完全愿意调整我的方法!预先感谢您的任何帮助。

// setup the layer hierarchy for drawing    
private func setupView() {
self.mainDrawLayer = CAShapeLayer()
self.mainDrawLayer.backgroundColor = UIColor.clear.cgColor
self.layer.addSublayer(self.mainDrawLayer)

// set up the mask. add an opaque background so everything shows through to start
self.maskLayer = CALayer()
let p = UIBezierPath.init(rect: self.bounds)
self.maskShapeLayer = CAShapeLayer()
self.maskShapeLayer?.fillColor = UIColor.black.cgColor
self.maskShapeLayer?.path = p.cgPath
self.maskLayer?.addSublayer(self.maskShapeLayer!)

// apply the mask
self.layer.mask = self.maskLayer
}

override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)

guard let touch = touches.first else {
return
}

var erasing = false


// setup the currentDrawLayer which captures the bezier path
self.currentDrawLayer = CAShapeLayer()
self.currentDrawLayer?.lineCap = CAShapeLayerLineCap.round
self.currentDrawLayer?.fillColor = nil

// set the ink color to use for drawing
if let ink = UserDefaults.standard.string(forKey: "ink") {
self.currentDrawLayer?.strokeColor = UIColor(hex: ink)?.cgColor
} else {
self.currentDrawLayer?.strokeColor = UIColor(hex: Constants.inkBlack3)?.cgColor
}

if UserDefaults.standard.string(forKey: "ink") == Constants.inkBlack5 {
// removing the filter makes white overlay other colors
// this is essentially erasing with a white background
self.currentDrawLayer?.compositingFilter = nil
} else {
// this blend mode ads a whole different feeling to the drawing!
self.currentDrawLayer?.compositingFilter = "darkenBlendMode"
}

// THIS IS THE ERASER COLOR!
if UserDefaults.standard.string(forKey: "ink") == Constants.inkBlack4 {
// trying erasing via drawing with clear
self.currentDrawLayer?.strokeColor = UIColor.clear.cgColor
// is there a compositingFilter available to 'combine' my clear color with the black opaque mask layer created above?
self.currentDrawLayer?.compositingFilter = "iDontHaveADamnClueIfTheresOneThatWillWorkIveTriedThemAllItSeems:)"

erasing = true

}

self.currentDrawLayer?.path = self.mainDrawPath.cgPath

if erasing {
// add the layer to the masks
self.maskLayer!.addSublayer(self.currentDrawLayer!)
} else {
// add the layer to the drawings
self.layer.addSublayer(self.currentDrawLayer!)
}

let location = touch.location(in: self)

self.ctr = 0
self.pts[0] = location
}

最佳答案

我只能通过附加到蒙版形状图层的路径来完成类似的事情。

        CALayer *penStroke = ... the layer that has all the pen strokes ...;

UIBezierPath *eraserStroke = [[UIBezierPath bezierPathWithRect:[self bounds]] bezierPathByReversingPath];
[eraserStroke appendPath:[UIBezierPath bezierPathWithRect:CGRectMake(110, 110, 200, 30)]];

CAShapeLayer *maskFill = [CAShapeLayer layer];
maskFill.path = [eraserStroke CGPath];
maskFill.fillRule = kCAFillRuleEvenOdd;
maskFill.fillColor = [[UIColor blackColor] CGColor];
maskFill.backgroundColor = [[UIColor clearColor] CGColor];

penStroke.mask = maskFill;

以上将用所有橡皮擦笔画掩盖所有笔画。但绘图应用程序希望能够覆盖之前的橡皮擦笔画。我相信需要通过不断地用另一个新的 penStroke 层包裹现有的 penStroke 层,并始终将 penStrokes 添加到最外层来处理。

这会给出类似的内容:

 - Layer C: most recent pen strokes
- mask: no mask, so that all strokes are pen strokes
- Layer B: sublayer of layer C, contains some previous pen strokes
- Layer B's mask: most recent eraser strokes
- Layer A: sublayer on Layer B, contains pen strokes before the most recent eraser strokes
- Layer A's mask: eraser strokes before layer B's pen strokes

希望这是有道理的。基本上,它是嵌套层/蒙版。每次用户从笔 -> 橡皮擦或橡皮擦 -> 笔切换时,一个新的图层将包裹在所有现有的笔/橡皮擦笔画图层周围。

关于ios - 有没有办法在 Swift 中使用 CAShapeLayer.compositingFilters 来合成蒙版?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54702696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com