我假设你在代码中没有显示的地方做了这件事:
self.view.wantsLayer = true
但你也会想这样做:
self.view.layerUsesCoreImageFilters = true
结果
没有
这条线:
结果
具有
这条线:
(不管怎样,不要问我为什么“CIGaussianBlur”有效……)
编辑
-我用来产生上述输出的确切代码:
import CoreImage
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true
self.view.layerUsesCoreImageFilters = true
let mainLayer = CALayer()
let shapeLayer = CAShapeLayer()
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [NSColor.red.cgColor, NSColor.white.cgColor, NSColor.yellow.cgColor, NSColor.black.cgColor]
shapeLayer.path = CGPath(rect: CGRect(x: 0, y: 0, width: 500, height: 500), transform: nil)
shapeLayer.fillColor = CGColor.black
gradientLayer.frame = CGRect(x: 0, y: 0, width: 500, height: 500)
gradientLayer.mask = shapeLayer
gradientLayer.setAffineTransform(CGAffineTransform(translationX: 50, y: 50))
mainLayer.addSublayer(gradientLayer)
mainLayer.filters = []
self.view.layer?.addSublayer(mainLayer)
CustomFilterRegister.register()
let t = 2
if t == 1 {
if let image = NSImage(named: "test"), let cgImage = image.cgImage(forProposedRect: nil, context: nil, hints: nil) {
if let filter = CIFilter(name: "CustomFilter") {
filter.setValue(CIImage(cgImage: cgImage), forKey: kCIInputImageKey)
let output = filter.outputImage
print()
}
}
}
else if t == 2 {
if let filter = CIFilter(name: "CustomFilter") {
filter.name = "custom"
mainLayer.filters?.append(filter)
}
} else {
if let filter = CIFilter(name: "CIGaussianBlur") {
filter.name = "blur"
mainLayer.filters?.append(filter)
}
}
}
}
class CustomFilter: CIFilter {
override class var supportsSecureCoding: Bool {
return true
}
@objc dynamic var inputImage: CIImage?
@objc dynamic var inputSaturation: CGFloat = 1
@objc dynamic var inputBrightness: CGFloat = 0
@objc dynamic var inputContrast: CGFloat = 1
override func setDefaults() {
inputSaturation = 1
inputBrightness = 0
inputContrast = 2
}
override public var outputImage: CIImage? {
guard let image = inputImage else {
return nil
}
return image.applyingFilter("CIPhotoEffectProcess")
.applyingFilter("CIColorControls", parameters: [
kCIInputSaturationKey: inputSaturation,
kCIInputBrightnessKey: inputBrightness,
kCIInputContrastKey: inputContrast
])
}
}
class CustomFilterRegister: CIFilterConstructor {
static func register() {
CIFilter.registerName(
"CustomFilter", constructor: CustomFilterRegister(),
classAttributes: [
kCIAttributeFilterCategories: [kCICategoryBlur, kCICategoryVideo, kCICategoryStillImage]
])
}
func filter(withName name: String) -> CIFilter? {
switch name {
case "CustomFilter":
return CustomFilter()
default:
return nil
}
}
}
编辑
奇怪的是,如果我添加一个计数器var和
print()
这样的陈述:
var applyCount: Int = 0
override public var outputImage: CIImage? {
print("getting outputImage...")
guard let image = inputImage else {
return nil
}
applyCount += 1
print("apply", applyCount)
return image.applyingFilter("CIPhotoEffectProcess")
.applyingFilter("CIColorControls", parameters: [
kCIInputSaturationKey: inputSaturation,
kCIInputBrightnessKey: inputBrightness,
kCIInputContrastKey: inputContrast
])
}
在macOS 10.15.4/XXcode 12.4上,我在调试控制台中得到以下结果:
getting outputImage...
apply 1
getting outputImage...
apply 2
getting outputImage...
apply 3
getting outputImage...
apply 4
getting outputImage...
apply 5
getting outputImage...
apply 6
getting outputImage...
apply 7
getting outputImage...
apply 8
getting outputImage...
apply 9
getting outputImage...
apply 10
getting outputImage...
apply 11
getting outputImage...
apply 12
getting outputImage...
apply 13
getting outputImage...
apply 14
getting outputImage...
apply 15
getting outputImage...
apply 16
(例如,当窗口改变大小时,它会继续被重复调用)。
但是,在macOS 11.4/Xcode 12.5.1上运行时,我得到
没有什么
在调试控制台中。。。
outputImage
从未被请求?