https://www.objc.io/books/functional-swift/preview/
Thinking Functionally,用一个处理图片的示例,向我们暂时如何函数式的思考问题。
//定义一个闭包
typealias Filter = CIImage -> CIImage
//模糊化
func blur(radius: Double) -> Filter {
return { image in
let parameters = [
kCIInputRadiusKey: radius,
kCIInputImageKey: image
]
guard let filter = CIFilter(name: "CIGaussianBlur",
withInputParameters: parameters) else { fatalError() }
guard let outputImage = filter.outputImage else { fatalError() }
return outputImage
}
}
//生成颜色
func colorGenerator(color: NSColor) -> Filter {
return { _ in
guard let c = CIColor(color: color) else { fatalError() }
let parameters = [kCIInputColorKey: c]
guard let filter = CIFilter(name: "CIConstantColorGenerator",
withInputParameters: parameters) else { fatalError() }
guard let outputImage = filter.outputImage else { fatalError() }
return outputImage
}
}
//圆角处理等
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() }
let cropRect = image.extent
return outputImage.imageByCroppingToRect(cropRect)
}
}
//
func colorOverlay(color: NSColor) -> Filter {
return { image in
let overlay = colorGenerator(color)(image)
return compositeSourceOver(overlay)(image)
}
}
let url = NSURL(string: "http://www.objc.io/images/covers/16.jpg")!
let image = CIImage(contentsOfURL: url)!
let blurRadius = 5.0
let overlayColor = NSColor.redColor().colorWithAlphaComponent(0.2)
let blurredImage = blur(blurRadius)(image)
let overlaidImage = colorOverlay(overlayColor)(blurredImage)
//这样写真的容易读吗?
let result = colorOverlay(overlayColor)(blur(blurRadius)(image))
//定义合并两个操作
func composeFilters(filter1: Filter, _ filter2: Filter) -> Filter {
return { image in filter2(filter1(image)) }
}
//似乎好读了,但是,还不够明显
let myFilter1 = composeFilters(blur(blurRadius), colorOverlay(overlayColor))
let result1 = myFilter1(image)
//定义一个类似于pipe的操作。
infix operator >>> { associativity left }
func >>> (filter1: Filter, filter2: Filter) -> Filter {
return { image in filter2(filter1(image)) }
}
//最后的修饰
let myFilter2 = blur(blurRadius) >>> colorOverlay(overlayColor)
let result2 = myFilter2(image)
let myFilter3 = colorOverlay(overlayColor) >>> blur(blurRadius)