美文网首页
封装 Core Image 的 API - 高阶函数方式

封装 Core Image 的 API - 高阶函数方式

作者: ixialuo | 来源:发表于2018-12-20 21:32 被阅读0次

上一篇:封装 Core Image 的 API - 延展方式

Why

  • Core Image 是一个强大的图像处理框架,但是它的 API 有时可能略显笨拙
  • Core Image 的 API 是弱类型的 —— 我们通过键值编码 (KVC) 来配置图像滤镜 (filter)
  • 在使用参数的类型或名字时,我们都使用字符串来进行表示,这十分容易出错,极有可能导致运行时错误

Method & Advantage

Method

函数式编程开发新的 API

Advantage

避免这些运行时错误,最终将得到一组类型安全而且高度模块化的 API

Usage

效果图
调用代码
if let url = URL(string: "https://via.placeholder.com/300x180/62abe4/ffffff?text=IFilter"), let image = CIImage(contentsOf: url) {
    
    // 原图
    filterImageViews[0].image = UIImage(ciImage: image)
    
    // 高斯模糊滤镜
    filterImageViews[1].image = UIImage(ciImage: blur(radius: 2)(image))
    /**
    // 对应的延展方式实现同样效果
    filterImageViews[1].image = UIImage(ciImage: image.blurred(radius: 2))
    */
    
    // 颜色生成滤镜
    let color = UIColor.orange.withAlphaComponent(0.4)
    filterImageViews[2].image = UIImage(ciImage: generate(color: color)(image))
    /**
    // 对应的延展方式实现同样效果
    filterImageViews[2].image = UIImage(ciImage: image.generated(color: color))
    */
    
    // 颜色叠层滤镜
    filterImageViews[3].image = UIImage(ciImage: overlay(color: color)(image))
    /**
    // 对应的延展方式实现同样效果
    filterImageViews[3].image = UIImage(ciImage: image.overlaid(color: color))
    */
    
    // 复合函数组合滤镜
    let blurAndOverlay1 = compose(filter: blur(radius: 2), with: overlay(color: color))
    filterImageViews[4].image = UIImage(ciImage: blurAndOverlay1(image))
    /**
    // 对应的延展方式实现同样效果
    filterImageViews[4].image = UIImage(ciImage: image.blurred(radius: 2).overlaid(color: color))
    */
    
    // 自定义运算符组合滤镜
    let blurAndOverlay2 = blur(radius: 2) >>> overlay(color: color)
    filterImageViews[5].image = UIImage(ciImage: blurAndOverlay2(image))
    /**
    // 对应的延展方式实现同样效果
    filterImageViews[5].image = UIImage(ciImage: image.blurred(radius: 2).overlaid(color: color))
    */
}

Implementation

Filter类型
public typealias Filter = (CIImage) -> CIImage

Filter 类型定义为一个函数,该函数接受一个图像作为参数并返回一个新的图像

1、高斯模糊滤镜(CIGaussianBlur)
// 1.高斯模糊滤镜(CIGaussianBlur)
func blur(radius: Double) -> Filter {
    return { image in
        let parameters: [String: Any] = [
            kCIInputRadiusKey: radius,
            kCIInputImageKey: image
        ]
        guard let filter = CIFilter(name: "CIGaussianBlur", parameters: parameters) else {
            fatalError("CIGaussianBlur filter creation failed!")
        }
        guard let outputImage = filter.outputImage else {
            fatalError("CIGaussianBlur outputImage generation failed!")
        }
        return outputImage
    }
}
2、颜色生成滤镜(CIConstantColorGenerator)
// 2.颜色生成滤镜(CIConstantColorGenerator)
public func generate(color: UIColor) -> Filter {
    return { image in
        let parameters: [String: Any] = [
            kCIInputColorKey: CIColor(cgColor: color.cgColor)
        ]
        guard let filter = CIFilter(name: "CIConstantColorGenerator", parameters: parameters) else {
            fatalError("CIConstantColorGenerator filter creation failed!")
        }
        guard let outputImage = filter.outputImage else {
            fatalError("CIConstantColorGenerator outputImage generation failed!")
        }
        return outputImage.cropped(to: image.extent)
    }
}
3、图像覆盖合成滤镜(CISourceOverCompositing)
// 3.图像覆盖合成滤镜(CISourceOverCompositing)
func compositeSource(over dest: CIImage) -> Filter {
    return { image in
        let parameters: [String: Any] = [
            kCIInputBackgroundImageKey: dest,
            kCIInputImageKey: image
        ]
        guard let filter = CIFilter(name: "CISourceOverCompositing", parameters: parameters) else {
            fatalError("CISourceOverCompositing filter creation failed!")
        }
        guard let outputImage = filter.outputImage else {
            fatalError("CISourceOverCompositing outputImage generation failed!")
        }
        return outputImage.cropped(to: image.extent)
    }
}
4、颜色叠层滤镜
// 4.颜色叠层滤镜
public func overlay(color: UIColor) -> Filter {
    return { image in
        let overlay = generate(color: color)(image)
        return compositeSource(over: image)(overlay)
    }
}
5、复合函数组合滤镜
// 5.复合函数
public func compose(filter filter1: @escaping Filter, with filter2: @escaping Filter) -> Filter {
    return { image in
        filter2(filter1(image))
    }
}
6、自定义运算符组合滤镜
// 6.自定义运算符组合滤镜
infix operator >>>
public func >>>(filter1: @escaping Filter, filter2: @escaping Filter) -> Filter {
    return { image in
        filter2(filter1(image))
    }
}

Contact

QQ: 2256472253
Email: ixialuo@126.com

Github

下载Demo

函数式编程引用来自 Chris Eidhof 的 《函数式 Swift》

相关文章

网友评论

      本文标题:封装 Core Image 的 API - 高阶函数方式

      本文链接:https://www.haomeiwen.com/subject/fqpykqtx.html