封裝 Core Image 的 API - 高階函數(shù)方式

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

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

下載Demo

函數(shù)式編程引用來自 Chris Eidhof 的 《函數(shù)式 Swift》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市机断,隨后出現(xiàn)的幾起案子楷拳,更是在濱河造成了極大的恐慌绣夺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欢揖,死亡現(xiàn)場離奇詭異陶耍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)她混,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門烈钞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坤按,你說我怎么就攤上這事毯欣。” “怎么了晋涣?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵仪媒,是天一觀的道長。 經(jīng)常有香客問我谢鹊,道長算吩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任佃扼,我火速辦了婚禮偎巢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兼耀。我一直安慰自己压昼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布瘤运。 她就那樣靜靜地躺著窍霞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拯坟。 梳的紋絲不亂的頭發(fā)上但金,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機(jī)與錄音郁季,去河邊找鬼冷溃。 笑死,一個胖子當(dāng)著我的面吹牛梦裂,可吹牛的內(nèi)容都是我干的似枕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼年柠,長吁一口氣:“原來是場噩夢啊……” “哼凿歼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤毅往,失蹤者是張志新(化名)和其女友劉穎牵咙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攀唯,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洁桌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侯嘀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片另凌。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖戒幔,靈堂內(nèi)的尸體忽然破棺而出吠谢,到底是詐尸還是另有隱情,我是刑警寧澤诗茎,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布工坊,位于F島的核電站,受9級特大地震影響敢订,放射性物質(zhì)發(fā)生泄漏王污。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一楚午、第九天 我趴在偏房一處隱蔽的房頂上張望昭齐。 院中可真熱鬧,春花似錦矾柜、人聲如沸阱驾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽里覆。三九已至,卻和暖如春缆瓣,著一層夾襖步出監(jiān)牢的瞬間喧枷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工捆愁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窟却。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓昼丑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夸赫。 傳聞我的和親對象是個殘疾皇子菩帝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 原鏈接:http://www.csdn.net/article/2015-02-13/2823961-core-i...
    hament閱讀 1,012評論 0 1
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,102評論 4 62
  • 如果你多飲一杯美酒呼奢, 世界會不會也憑空 多出一杯幸福宜雀? 如果你贊美一個清麗 干凈的女孩, 她微笑握础, 喜愛自己辐董, 世...
    蟬月清風(fēng)1234閱讀 202評論 0 1
  • 時間一晃三年多简烘,是我在北京的日子。 我已經(jīng)忘了我剛到北京時的模樣定枷,我以為經(jīng)過社會的淘米水孤澎,會蛻變或者面目全非,當(dāng)我...
    燈_2513閱讀 1,064評論 0 1
  • 一 獨(dú)立精神 就是善待別人欠窒,但不期望被別人善待覆旭。獨(dú)立精神的人會感恩,因?yàn)閷e人沒有要求岖妄,沒有過多的苛求型将,就是我愛你...
    梁萌萌_8870閱讀 259評論 0 0