我想应用一个给定的CIFilter,但不是立即显示的效果,我想动画它。例如,我希望将一幅彩色图像去饱和为超过2秒的灰度,或者通过使用EaseInOut动画曲线在0.8秒以上将其去解析成全分辨率图像来解析块图像。
如果您使用的是内置的SwiftUI视图修饰符之一,比如.blur(),那么您就是黄金。只要附加一些.animate()变体,您就完成了。
但是,考虑到您必须跳过UIImage、CGImage、CIImage路由,或者是WWDC 2022示例代码中的MTLView、CIRenderDestination、ContentView示例,我有点困惑。
理想情况下,我想我只想为我想做的每一个效果编写视图修饰符,这样它们就可以和SwiftUI内置的效果一样可用,但我不知道这是否可能。有一种幸运的方法吗?有什么想法吗?
发布于 2022-06-27 12:28:14
下面是一种适应Animatable
的方法。您可以轻松地使其适应您的需要:
struct ContentView: View {
@State private var animate = false
var body: some View {
VStack {
PixellatedImage(imageName: "yoga", scale: animate ? 100 : 1)
.scaledToFit()
}
.padding()
.onAppear {
withAnimation(Animation.linear(duration: 3.0).repeatForever()) {
self.animate.toggle()
}
}
}
}
struct PixellatedImage: View, Animatable {
let imageName: String
var scale: CGFloat
var animatableData: CGFloat {
get { scale }
set { scale = newValue }
}
var body: some View {
Image(uiImage: pixellatedImage(imageName: imageName, scale: scale))
.resizable()
}
}
func pixellatedImage(imageName: String, scale: Double) -> UIImage {
if let inputImage = UIImage(named: imageName) {
let context = CIContext(options: nil)
if let currentFilter = CIFilter(name: "CIPixellate") {
let beginImage = CIImage(image: inputImage)
currentFilter.setValue(beginImage, forKey: kCIInputImageKey)
currentFilter.setValue(scale, forKey: kCIInputScaleKey)
if let output = currentFilter.outputImage {
if let cgimg = context.createCGImage(output, from: output.extent) {
let processedImage = UIImage(cgImage: cgimg)
return processedImage
}
}
}
}
return UIImage() // empty default instead of nil
}
https://stackoverflow.com/questions/72776365
复制相似问题