【发布时间】:2021-08-16 19:26:59
【问题描述】:
我们正在尝试创建一个自定义 CIFilter 以添加到我们的 CALayer's. 之上但是似乎只有默认 CIFilters 可以在 CALayer. 上工作
我们在添加的ViewController.swift 上创建了一个小型新项目:
import Cocoa
import CoreImage
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create some layers to work with! (square with gradient color)
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)
// Register the custom filter
CustomFilterRegister.register()
// Test with a normal image file, WORKS!
// 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
// // WORKS! Image filtered as expected!
// }
// }
// Does NOT work. No change in color of the layer!
if let filter = CIFilter(name: "CustomFilter") {
filter.name = "custom"
mainLayer.filters?.append(filter)
}
// This works: mainLayer and sublayers are blurred!
// if let filter = CIFilter(name: "CIGaussianBlur") {
// filter.name = "blur"
// mainLayer.filters?.append(filter)
// }
}
}
}
我们创建了一个简单的自定义 CIFilter 以在开始构建自定义 CIFilter. 之前进行第一次尝试
class CustomFilter: CIFilter {
// Error in xcode if you don't add this in!
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
}
}
}
在 ViewController 中,我们添加了代码以使用普通图像进行测试。这确实有效,因此过滤器似乎没问题。我们还尝试了默认的CIGaussianBlur,它确实适用于CALayer.
我们不知道需要什么才能让自定义 CIFilter 与 CALayer, 一起使用,并且似乎找不到任何相关信息。
请注意,我们不是在寻找这种类型的 CIFilter 或其他方式来获取过滤器结果。我们需要一个自定义的CIFilter 来处理CALayer.
【问题讨论】:
-
可能的愚蠢问题,但只是想提供帮助。您已标记此 [macos]。 iOS 上的 CoreImage 和 macOS 之间存在许多差异——不,我没有资格说明它们。你的代码有可能在 iOS 中运行吗?
-
@dfd 你不能在 iOS 中将过滤器附加到层,所以 OP 的代码在 iOS 设备上肯定会失败。
-
正如我所说,一个可能很愚蠢的问题
-
确实标记了 macOS 是有原因的 ????。正如代码所述,内置 CIFilter 在直接调用时确实有效。
标签: swift xcode macos calayer cifilter