《函数式swift》学习一

###案例研究:封装Core Image

  • 这个案例是通过一个已经存在且面向对象的API,展示如何使用高阶函数将其以小巧且函数式的方式进行。

1.首先是定义一个闭包,并且重命名。该闭包接受一个CIImage并返回一个CIImage。

typealias Filter = (CIImage) -> CIImage
复制代码

2.构建一个模糊滤镜

//模糊滤镜
    func blur(radius: Double) -> Filter{
        return { image in
            let parameters:[String: Any] = [
                kCIInputRadiusKey: radius,
                kCIInputImageKey:image
            ]
            
            guard let filter = CIFilter(name: "CIGaussianBlur", withInputParameters: parameters) else{
                fatalError("错误1")
            }
            
            guard let outputImage = filter.outputImage else{
                fatalError("错误二")
            }
            
            return outputImage
        }
    }
复制代码

3.颜色叠层,颜色叠层在调用的时候会导致程序崩溃,这里应该有点儿问题,不过理解到里面的思想就行了。

//固定颜色滤镜
    func generate(color: UIColor) -> Filter{
        return { _ in
            
            let parameters = [
                kCIInputColorKey:CIColor(cgColor: color.cgColor)
            ]
            
            guard let filter = CIFilter(name: "CIConstantColorGenerator", withInputParameters: parameters) else{
                fatalError(".....")
            }
            
            guard let outputImage = filter.outputImage else {
                fatalError("''''''''")
            }
            
            return outputImage
        }
    }
复制代码

4.合成滤镜

//合成滤镜
    func compositeSourceOver(overlay: CIImage) -> Filter{
        return { image in
            let parameters = [
                kCIInputBackgroundImageKey:image,
                kCIInputImageKey:overlay
            ]
            
            guard let filter = CIFilter(name: "CISourceOverCompositing", withInputParameters: parameters) else{
                fatalError()
            }
            
            guard let outputImage = filter.outputImage else {
                fatalError()
            }
            
            
            return outputImage
        }
    }
复制代码

5.再创建一个通过两个滤镜来创建颜色叠层滤镜。这里是用先前创建颜色生成滤镜generate(color:)来生成一个新叠层。然后以gennerate(color:)返回的CIImage作为compositeSourceOver(overlay:)参数调用该函数,返回Filter类型值。这里就很明显了任何滤镜之间可以相互组合,特别的灵活。

//滤镜颜色叠成
    func overlay(color:UIColor) -> Filter{
        return { image in
            let overlay = self.generate(color: color)(image).cropping(to: image.extent)
            return self.compositeSourceOver(overlay: overlay)(image)
        }
    }
复制代码

6.所以我们可以创建一个将两个任意生成滤镜方法进行组合

//简化函数
    func compose(filter filter1:@escaping Filter, with filter2:@escaping Filter) -> Filter{
        return {image in filter2(filter1(image))}
    }
复制代码

7.为了防代码更具有可读性,我们还可以再进行一步,为组合滤镜引入自定义运算符。

infix operator >>>
//自定义个运算符
func >>> (filter1:@escaping Filter,filter2:@escaping Filter) -> Filter{
    return {image in filter2(filter1(image))}
}
复制代码

###柯里化 -将一个接受多个参数的函数变换为一系列只接受单个参数的函数,这个过程被称为柯里化。这个列子add2称为add1的柯里化版本。

func add1(_ x: Int, _ y: Int) -> Int{
        return x + y
    }
    
func add2(_ x: Int) -> ((Int) -> Int){
        return {y in x + y}
    }
复制代码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值