Why
- Core Image 是一個強(qiáng)大的圖像處理框架春畔,但是它的 API 有時可能略顯笨拙
- Core Image 的 API 是弱類型的 —— 我們通過鍵值編碼 (KVC) 來配置圖像濾鏡 (filter)
- 在使用參數(shù)的類型或名字時女轿,我們都使用字符串來進(jìn)行表示卵蛉,這十分容易出錯蜕乡,極有可能導(dǎo)致運(yùn)行時錯誤
Method & Advantage
Method
函數(shù)式編程開發(fā)新的 API
Advantage
避免這些運(yùn)行時錯誤蜀踏,最終將得到一組類型安全而且高度模塊化的 API
Usage
效果圖
調(diào)用代碼
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))
/**
// 對應(yīng)的延展方式實(shí)現(xiàn)同樣效果
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))
/**
// 對應(yīng)的延展方式實(shí)現(xiàn)同樣效果
filterImageViews[2].image = UIImage(ciImage: image.generated(color: color))
*/
// 顏色疊層濾鏡
filterImageViews[3].image = UIImage(ciImage: overlay(color: color)(image))
/**
// 對應(yīng)的延展方式實(shí)現(xiàn)同樣效果
filterImageViews[3].image = UIImage(ciImage: image.overlaid(color: color))
*/
// 復(fù)合函數(shù)組合濾鏡
let blurAndOverlay1 = compose(filter: blur(radius: 2), with: overlay(color: color))
filterImageViews[4].image = UIImage(ciImage: blurAndOverlay1(image))
/**
// 對應(yīng)的延展方式實(shí)現(xiàn)同樣效果
filterImageViews[4].image = UIImage(ciImage: image.blurred(radius: 2).overlaid(color: color))
*/
// 自定義運(yùn)算符組合濾鏡
let blurAndOverlay2 = blur(radius: 2) >>> overlay(color: color)
filterImageViews[5].image = UIImage(ciImage: blurAndOverlay2(image))
/**
// 對應(yīng)的延展方式實(shí)現(xiàn)同樣效果
filterImageViews[5].image = UIImage(ciImage: image.blurred(radius: 2).overlaid(color: color))
*/
}
Implementation
Filter類型
public typealias Filter = (CIImage) -> CIImage
Filter 類型定義為一個函數(shù)屋摇,該函數(shù)接受一個圖像作為參數(shù)并返回一個新的圖像
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垒迂、復(fù)合函數(shù)組合濾鏡
// 5.復(fù)合函數(shù)
public func compose(filter filter1: @escaping Filter, with filter2: @escaping Filter) -> Filter {
return { image in
filter2(filter1(image))
}
}
6械姻、自定義運(yùn)算符組合濾鏡
// 6.自定義運(yùn)算符組合濾鏡
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
函數(shù)式編程引用來自 Chris Eidhof 的 《函數(shù)式 Swift》