如何在普通UIView(而不是UIImage)上获得乘法混合模式

Jan*_*man 16 blend filter uiview uiimage ios

我的iPad应用程序中有一个图像,我基本上想在它上面放置一个彩色滤镜.为此我有一个彩色的UIView,它被掩盖到我放在图像上的某个形状.由于调整alpha并没有给我预期的效果,我想使用混合模式.

据我所知,你只能在图像上使用混合模式而不是普通视图.视图的颜色是动态的,所以我不能只使用图片.

我也尝试将视图光栅化为图像,但是所有像素和奇怪的东西,但也许我做错了.

因此,基本问题是:是否可以将混合模式应用于视图?或者我应该采取完全不同的方法来达到同一目标?

Sea*_*anA 7

看看CALayer的compositingFilter的文档:https : //developer.apple.com/documentation/quartzcore/calayer/1410748-compositingfilter

在颜色叠加视图上,您​​可以设置view.layer.compositingFilterCICategoryCompositeOperation来实现与其背后内容的融合。这是一些应用了混合混合模式的示例游乐场代码,用于对其进行测试(将其替换为UIImage(named: "")您自己的图像进行测试)

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
    override func loadView() {

        let mainView = UIView()
        self.view = mainView

        let image = UIImageView()
        image.translatesAutoresizingMaskIntoConstraints = false;
        image.image = UIImage(named: "maxresdefault.jpg")
        mainView.addSubview(image)

        let overlay = UIView()
        overlay.translatesAutoresizingMaskIntoConstraints = false;
        overlay.backgroundColor = .red
        overlay.layer.compositingFilter = "multiplyBlendMode"
        mainView.addSubview(overlay)

        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))
        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": view]))

        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))
        mainView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": overlay]))
    }
}

PlaygroundPage.current.liveView = MyViewController()
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案不再有效!在 iOS 13 中,设置 CALayer.compositingFilter 是一项无操作。还有其他人遇到这个问题吗?(2019年9月) (2认同)

Tre*_*v14 7

iOS 13,斯威夫特 5

关键是compositingFilter在适当的 CALayer 上设置属性(顶部的那个 - 它与它后面的任何东西混合)。颜色混合适用于 UIViews 或 CALayer 之间。您可以在这里找到混合模式CICategoryCompositeOperation。要使用过滤器,只需删除CI名称的第一个字母 & 小写(例如CIDivideBlendMode变成divideBlendMode)。下面是一些游乐场代码来说明:

import UIKit
import PlaygroundSupport

let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 900))
PlaygroundPage.current.liveView = view


let heightIncrement = view.frame.height / 13
let widthIncrement = view.frame.width / 7


// TOP EXAMPLE (UIViews)

let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,
                                          y: heightIncrement,
                                          width: widthIncrement * 3,
                                          height: heightIncrement * 5))
backgroundView.backgroundColor = .black
view.addSubview(backgroundView)

let overlayView1 = UIView(frame: CGRect(x: widthIncrement,
                                        y: heightIncrement * 2,
                                        width: widthIncrement * 5,
                                        height: heightIncrement))
overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView1.layer.compositingFilter = "darkenBlendMode"
view.addSubview(overlayView1)

let overlayView2 = UIView(frame: CGRect(x: widthIncrement,
                                        y: heightIncrement * 4,
                                        width: widthIncrement * 5,
                                        height: heightIncrement))
overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
overlayView2.layer.compositingFilter = "divideBlendMode"
view.addSubview(overlayView2)




// BOTTOM EXAMPLE (CALayers)

let backgroundLayer = CALayer()
backgroundLayer.frame = CGRect(x: widthIncrement * 2,
                               y: heightIncrement * 7,
                               width: widthIncrement * 3,
                               height: heightIncrement * 5)
backgroundLayer.backgroundColor = UIColor.black.cgColor
view.layer.addSublayer(backgroundLayer)

let overlayLayer1 = CALayer()
overlayLayer1.frame = CGRect(x: widthIncrement,
                             y: heightIncrement * 8,
                             width: widthIncrement * 5,
                             height: heightIncrement)
overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer1.compositingFilter = "darkenBlendMode"
view.layer.addSublayer(overlayLayer1)

let overlayLayer2 = CALayer()
overlayLayer2.frame = CGRect(x: widthIncrement,
                             y: heightIncrement * 10,
                             width: widthIncrement * 5,
                             height: heightIncrement)
overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
overlayLayer2.compositingFilter = "divideBlendMode"
view.layer.addSublayer(overlayLayer2)
Run Code Online (Sandbox Code Playgroud)

结果如下所示:

描述

我确认相同的代码在 iOS 中有效。这是视图控制器代码:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)


        let heightIncrement = view.frame.height / 13
        let widthIncrement = view.frame.width / 7


        // TOP EXAMPLE (UIViews)

        let backgroundView = UIView(frame: CGRect(x: widthIncrement * 2,
                                                  y: heightIncrement,
                                                  width: widthIncrement * 3,
                                                  height: heightIncrement * 5))
        backgroundView.backgroundColor = .black
        view.addSubview(backgroundView)

        let overlayView1 = UIView(frame: CGRect(x: widthIncrement,
                                                y: heightIncrement * 2,
                                                width: widthIncrement * 5,
                                                height: heightIncrement))
        overlayView1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
        overlayView1.layer.compositingFilter = "darkenBlendMode"
        view.addSubview(overlayView1)

        let overlayView2 = UIView(frame: CGRect(x: widthIncrement,
                                                y: heightIncrement * 4,
                                                width: widthIncrement * 5,
                                                height: heightIncrement))
        overlayView2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3)
        overlayView2.layer.compositingFilter = "divideBlendMode"
        view.addSubview(overlayView2)




        // BOTTOM EXAMPLE (CALayers)

        let backgroundLayer = CALayer()
        backgroundLayer.frame = CGRect(x: widthIncrement * 2,
                                       y: heightIncrement * 7,
                                       width: widthIncrement * 3,
                                       height: heightIncrement * 5)
        backgroundLayer.backgroundColor = UIColor.black.cgColor
        view.layer.addSublayer(backgroundLayer)

        let overlayLayer1 = CALayer()
        overlayLayer1.frame = CGRect(x: widthIncrement,
                                     y: heightIncrement * 8,
                                     width: widthIncrement * 5,
                                     height: heightIncrement)
        overlayLayer1.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
        overlayLayer1.compositingFilter = "darkenBlendMode"
        view.layer.addSublayer(overlayLayer1)

        let overlayLayer2 = CALayer()
        overlayLayer2.frame = CGRect(x: widthIncrement,
                                     y: heightIncrement * 10,
                                     width: widthIncrement * 5,
                                     height: heightIncrement)
        overlayLayer2.backgroundColor = UIColor.yellow.withAlphaComponent(0.3).cgColor
        overlayLayer2.compositingFilter = "divideBlendMode"
        view.layer.addSublayer(overlayLayer2)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是模拟器中的结果:

描述

  • 谢谢!您能否解释一下,您是如何发现可以在 compositingFilter 属性上使用“divideBlendMode”之类的字符串,而不是“CIDivideBlendMode”之类的字符串?在文档中有 `compositingFilter: Any?`,我不清楚如何使用它‍♂️ (2认同)