#74 CIFilter 實現濾鏡功能

原來想要的濾鏡可以自己動手做,但是漂亮的濾鏡還是要靠自己研究的

BeautiMe App © Copyright 2019 Joy. All rights reserved.

對~沒錯這就是我的APP第一頁,個人覺得擴充性很大,故第一頁保有彈性設計,未來還可以增加按鈕呢!

起初我也只是看著UIslider,不知道有何發展性,看著看著就發現平常美圖的app 才是真正最需要UIslider元件,於是我開始研究濾鏡,抱歉…又發現新大陸。

先放上小潘潘的🧚🏼‍♂️

。參考文件:

。相關CIFilter文件:

。APPCODA文章

看了很多文章,大概知道怎麼做了..

但每個人遇到情況都會不一樣,我會以我的方向去紀錄🧚🏼‍♀️

。簡短筆記一下:

盡量將濾鏡事件當成func去call,會對流程比較乾淨

1.做濾鏡前,需要將UIImage -> CIImage

(因為CIFilter只會對CIImage產生作用,一定要先轉過去才能用,

UIImage看是要本地產生還是imageView.image取出)

let ciImage = CIImage(image: uiImage)

2.產生濾鏡物件 CIFilter(name: “哪一類的濾鏡”)

但因為可能產生失敗,所以要用「 if let」 加以判斷

let filter = CIFilter(name: “CIColorControls”)

3.傳入

待改的CIImage ,kCIInputImageKey告訴他前面參數放image哦

傳入

欲改多少值,kCIInputBrightnessKey 告訴他哪一個效果

filter.setValue(ciImage, forKey: kCIInputImageKey)filter.setValue(sliderValue, forKey: kCIInputBrightnessKey)

4.接下來就可以從filter輸出image

但絕對不要直接使用,因為會跟你原本的不一樣大,一定要透過CIContext的createCGImage()去調整

from: 是用於設定圖像的大小(extent:意思指圖像大小)

if let outputImage = filter.outputImage,   let cgImage = context.createCGImage(outputImage, 
from: outputImage.extent) {

否則就會看到,慘狀🥺

很多文章提到了CIContext()這件事情,所以我也去官方看了一下,

他說產生就是一件很昂貴很奢侈事情,看來是很吃效能,所以記得要在init產生,並且重複再重複利用。

所以,

只需要創建一次CIContext,只需要將context對象存起来,

供其他地方調用即可,不管我有幾個濾鏡效果都用同個CIContext

5.得到CGImage 可以直接轉回UIImage ,放回view上

let image = UIImage(cgImage: cgImage)

所以我做的func 可能就會是傳入必要資料,然後去使用,再丟出UIImage

func BrightnessFilter(uiImage:UIImage, sliderValue: CGFloat) -> UIImage {}

其中遇到一個比較大的問題是原來每個效果都有自己的特性

每個效果都有自己的區間值,還有Default值,所以要查清楚才會設計對

不然就會跟我一樣,設計錯誤導致debug不出來。

錯誤樣子

看不出來哪裡有問題吧😅

。以曝光度為例,區間值-1~1,

-1: 曝光度低0: 原始照片無效果1: 曝光度高

我把UISlider區間設定為0~1 ,Default就給中間值0.5

所以我一開始0.5時,照理來說要是原始照片無效果,沒想到0.5很有效果!

所以區間不能錯之外,UISlider也要從中間開始跑才對,

中間值通常表示原始照片

。如果想知道個效果的值域,可以在viewdidload()時print出來看

  • (name: “哪一類的濾鏡”)

他就會在下面告訴你你設計的slider區間值還有Default值

print(CIFilter(name: “CIColorControls”)?.attributes ?? “”)

其他小問題可能就是 每次使用濾鏡時,一定要用最原始的照片,如果沒有用的話,你只會把效果疊加的越深,安餒丟母湯了!

。實際Demo

ps: 保存成功需加上訊息提示
  • 因為在slider元件上。Continuous Updates屬性會讓slider值保持更新,導致模擬器看起來會很頓,故我在錄製畫面時,先關閉此屬性,讓我的螢幕錄製可以順暢,所以拉動slider值未更動並不是bug哦!
  • 在實機上,可能就不會發生此問題,但也要搭配ios13實機執行,故以模擬器做螢幕錄製

還有很多小細節未達成,此版還會持續更新,

想繼續看下去在幫我點個拍拍手哦,謝謝。

//code我暫時不放上來,應該對大家滿ez的!我想先繼續寫下去..

--

--

奇妙仙子
彼得潘的 Swift iOS / Flutter App 開發教室

When you want something, all the universe conspires in helping you to achieve it.