2015年1月23日 星期五

Core Image Filter 以模糊影像為例

一般常見的UI特效之一就是模糊背景讓使用中的UI更明顯,像是下圖:
彈出選單未啟動時的畫面

彈出選單啟動,背景霧化
這樣的處理會讓UI看來更有質感。以往這類的效果會牽扯到GPU或CPU的運算,開發者必須使用OpenGL這類C++的函式庫來處理,在iOS5之後apple提供了簡單的用具來協助使用者處理這些細節。詳細的資料請閱讀(CoreImage的官方文件)

apple提供了數十種不同的濾鏡效果供開發者選擇,詳細的濾鏡效果和參數請參閱(Core Image Filter的官方文件)廢話不多說,開始寫code吧:

首先,我建議各位把霧化效果的方法放在UIImage的Category區段裡面,這是為了程式的可讀性。所以我們先來做個Category區段:
@implementation UIImage (Blur_and_Color_Filter)
@end
這樣我們就可以用UIImage呼叫在Category區段的方法,剩下的工作就是選擇適合濾鏡和輸入參數了,apple提供的模糊濾鏡有很多種,有些是專屬OS X的,在這邊我們將使用高斯模糊"Gaussian Blur",其原理請參考這個網頁。在使用高斯模糊後,我們會產生一些問題:

  1. 影像會擴張,這是由於高斯模糊是把像素周圍的RGBA值取平均,所以本來圖片周圍不該有像素的地方也會被填入像素。
  2. 影像周圍的模糊效果較不明顯,這也是因為原本邊緣的像素被取平均後的後遺症,這的狀況會隨著模糊半徑越大越明顯。

為了解決問題我們在使用濾鏡的時候必須注意:

  1. 模糊後必須把圖片做適當的裁切,通常是input多大的圖,output的圖就裁剪成多大。
  2. 模糊半徑不宜設得太大,範例圖的模糊半徑是4。

接著我們把方法加入區段裡面吧:

@implementation UIImage (Blur_and_Color_Filter)
-(UIImage*)blurWithRadius:(CGFloat)radius{
    CIImage * inputImage = [CIImage imageWithCGImage:self.CGImage];
    CIFilter * blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [blurFilter setValue:inputImage forKey:@"inputImage"];
    [blurFilter setValue:[NSNumber numberWithFloat:radius] forKey:@"inputRadius"];
    CIImage * outputImage = [blurFilter outputImage];
    outputImage = [outputImage imageByCroppingToRect:[inputImage extent]];
    UIImage * blurImage = [UIImage imageWithCIImage:outputImage];
    return blurImage;
}
@end
完成這個區段後,我們在同一個project內就可以直接把UIImage用物件方法直接模糊化,輕鬆又方便。之後我打算介紹如何做一個自己的UIAlertView取代apple內建的AlertView(由UIViewController做起)。

沒有留言:

張貼留言