Core Image框架詳細(xì)解析(十七) —— 一個簡單說明和示例(一)

版本記錄

版本號 時間
V1.0 2018.08.08

前言

Core Image是IOS5中新加入的一個框架,里面提供了強(qiáng)大高效的圖像處理功能,用來對基于像素的圖像進(jìn)行操作與分析。還提供了很多強(qiáng)大的濾鏡,可以實(shí)現(xiàn)你想要的效果,下面我們就一起解析一下這個框架。感興趣的可以參考上面幾篇。
1. Core Image框架詳細(xì)解析(一) —— 基本概覽
2. Core Image框架詳細(xì)解析(二) —— Core Image濾波器參考
3. Core Image框架詳細(xì)解析(三) —— 關(guān)于Core Image
4. Core Image框架詳細(xì)解析(四) —— Processing Images處理圖像(一)
5. Core Image框架詳細(xì)解析(五) —— Processing Images處理圖像(二)
6. Core Image框架詳細(xì)解析(六) —— 圖像中的面部識別Detecting Faces in an Image(一)
7. Core Image框架詳細(xì)解析(七) —— 自動增強(qiáng)圖像 Auto Enhancing Images
8. Core Image框架詳細(xì)解析(八) —— 查詢系統(tǒng)中的過濾器 Querying the System for Filters
9. Core Image框架詳細(xì)解析(九) —— 子類化CIFilter:自定義效果的配方 Subclassing CIFilter: Recipes for Custom Effects(一)
10. Core Image框架詳細(xì)解析(十) —— 子類化CIFilter:自定義效果的配方 Subclassing CIFilter: Recipes for Custom Effects(二)
11. Core Image框架詳細(xì)解析(十一) —— 獲得最佳性能 Getting the Best Performance
12. Core Image框架詳細(xì)解析(十二) —— 使用反饋處理圖像 Using Feedback to Process Images
13. Core Image框架詳細(xì)解析(十三) —— 在寫一個自定義濾波器之前你需要知道什么?
14. Core Image框架詳細(xì)解析(十四) —— 創(chuàng)建自定義濾波器 Creating Custom Filters(一)
15. Core Image框架詳細(xì)解析(十五) —— 創(chuàng)建自定義濾波器 Creating Custom Filters(二)
16. Core Image框架詳細(xì)解析(十六) —— 包裝和加載圖像單元 Packaging and Loading Image Units

簡介

Core Image是一個功能強(qiáng)大的框架,可讓您輕松地將過濾器應(yīng)用于圖像。 您可以獲得各種效果,例如修改振動,色調(diào)或曝光。 它可以使用CPU或GPU來處理圖像數(shù)據(jù),速度非???- 足以快速實(shí)現(xiàn)視頻幀的處理。

Core Image濾鏡也可以鏈接在一起,一次將多種效果應(yīng)用于圖像或視頻幀。 多個濾鏡組合成一個應(yīng)用于圖像的濾鏡。 與通過每個濾波器處理圖像(一次一個)相比,這使得它非常有效。

在開始之前,讓我們討論一下Core Image框架中一些最重要的類:

  • CIContext。 core image的所有處理都在CIContext中完成。 這有點(diǎn)類似于Core GraphicsOpenGL上下文。
  • CIImage。 該類保存圖像數(shù)據(jù)。 它可以從UIImage,圖像文件或像素數(shù)據(jù)創(chuàng)建。
  • CIFilter。 CIFilter類有一個字典,用于定義它所代表的特定過濾器的屬性。 濾波器的示例是振動,顏色反轉(zhuǎn),裁剪等等。

上面三個類是關(guān)于Core Image使用時都要用到的類。


新建工程

首先我們新建立一個OC的工程,然后在sb中拖進(jìn)去一個imageView控件并設(shè)置好約束。

在代碼中指定圖像并設(shè)置填充模式,防止失真。

同樣,你也可以建立一個Swift工程,對于展示效果都是一樣的,只是使用語言表達(dá)方式的不同而已。


Basic Image Filtering - 基本圖像濾鏡

您只需通過CIFilter運(yùn)行圖像并將其顯示在屏幕上即可開始使用。每次要將CIFilter應(yīng)用于圖像時,都需要做四件事:

  • Create a CIImage object - 創(chuàng)建一個CIImage對象。 CIImage有幾種初始化方法,包括:CIImage(contentsOfURL :),CIImage(data:)CIImage(CGImage :),CIImage(bitmapData:bytesPerRow:size:format:colorSpace :)等等。您最有可能在大多數(shù)時間使用CIImage(contentsOfURL :)。
  • Create a CIContext - 創(chuàng)建一個CIContext。 CIContext可以是基于CPU或GPU的。初始化CIContext相對昂貴,因此您可以重復(fù)使用它而不是一遍又一遍地創(chuàng)建它。輸出CIImage對象時總是需要一個。
  • Create a CIFilter - 創(chuàng)建一個CIFilter。創(chuàng)建過濾器時,您可以在其上配置許多依賴于您正在使用的過濾器的屬性。
  • Get the filter output - 獲取過濾器輸出。過濾器為您提供輸出圖像作為CIImage - 您可以使用CIContext將其轉(zhuǎn)換為UIImage,如下所示。

讓我們看看它是如何工作的。將以下代碼添加到viewDidLoad中。

Swift版本

// 1
let fileURL = NSBundle.mainBundle().URLForResource("image", withExtension: "png")

// 2
let beginImage = CIImage(contentsOfURL: fileURL)

// 3
let filter = CIFilter(name: "CISepiaTone")
filter.setValue(beginImage, forKey: kCIInputImageKey)
filter.setValue(0.5, forKey: kCIInputIntensityKey)

// 4
let newImage = UIImage(CIImage: filter.outputImage)
self.imageView.image = newImage

讓我們逐節(jié)討論這個部分:

  • 1)此行創(chuàng)建一個NSURL對象,該對象包含圖像文件的路徑。
  • 2)接下來,使用CIImage(contentsOfURL :)構(gòu)造函數(shù)創(chuàng)建CIImage。
  • 3)接下來,您將創(chuàng)建CIFilter對象。 CIFilter構(gòu)造函數(shù)采用過濾器的名稱,以及指定該過濾器的鍵和值的字典。每個過濾器都有自己唯一的鍵和一組有效值。 CISepiaTone過濾器只接受兩個值,KCIInputImageKey(一個CIImage)和kCIInputIntensityKey,一個介于0和1之間的浮點(diǎn)值。這里給出的值為0.5。大多數(shù)過濾器都有默認(rèn)值,如果沒有提供值,將使用這些值。一個例外是CIImage,必須提供,因為沒有默認(rèn)值。
  • 4)從過濾器中取出CIImage就像使用outputImage屬性一樣簡單。一旦有了輸出CIImage,就需要將它轉(zhuǎn)換為UIImageUIImage(CIImage :)構(gòu)造函數(shù)從CIImage創(chuàng)建UIImage。將它轉(zhuǎn)換為UIImage后,只需將其顯示在之前添加的圖像視圖中即可。

構(gòu)建并運(yùn)行項目,您將看到通過棕褐色調(diào)過濾器過濾的圖像。

OC版本

直接看一下代碼

#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIImageView *picImageView;

@end

@implementation ViewController

#pragma mark -  Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //1
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"picture" withExtension:@".png"];
    
    //2
    CIImage *ciImage = [CIImage imageWithContentsOfURL:url];
    
    //3
    CIFilter *ciFilter = [CIFilter filterWithName:@"CISepiaTone"];
    [ciFilter setValue:ciImage forKey:kCIInputImageKey];
    [ciFilter setValue:@(0.5) forKey:kCIInputIntensityKey];
    
    //4
    UIImage *image = [UIImage imageWithCIImage:ciFilter.outputImage];
    self.picImageView.contentMode = UIViewContentModeScaleAspectFit;
    self.picImageView.image = image;
}

@end

運(yùn)行并查看效果,如下所示:


Putting It Into Context - 將它放在上下文中

在你繼續(xù)之前,你應(yīng)該知道一個優(yōu)化。

我之前提到你需要一個CIContext來應(yīng)用一個CIFilter,但在上面的例子中沒有提到這個對象。 事實(shí)證明,UIImage(CIImage :)構(gòu)造函數(shù)可以為您完成所有工作。 它創(chuàng)建一個CIContext并使用它來執(zhí)行過濾圖像的工作。 這使得使用Core Image API非常容易。

有一個主要缺點(diǎn) - 它每次使用時都會創(chuàng)建一個新的CIContext。 CIContext實(shí)例旨在可重用以提高性能。 如果您想使用滑塊更新過濾器值,就像您在本教程中所做的那樣,每次更改過濾器時創(chuàng)建一個新的CIContext都會太慢。

我們這樣做吧。 從添加到viewDidLoad()的代碼中刪除第4步,并將其替換為以下內(nèi)容:

Swift版本

// 1
let context = CIContext(options:nil)

// 2
let cgimg = context.createCGImage(filter.outputImage, fromRect: filter.outputImage.extent())

// 3
let newImage = UIImage(CGImage: cgimg)
self.imageView.image = newImage

再說一次,讓我們逐節(jié)討論。

  • 1)在這里,您可以設(shè)置CIContext對象并使用它來繪制CGImageCIContext(options :)構(gòu)造函數(shù)采用NSDictionary,它指定顏色格式等選項,或上下文是否應(yīng)在CPU或GPU上運(yùn)行。對于這個app,默認(rèn)值是正常的,所以你傳遞nil為該參數(shù)。
  • 2)使用提供的CIImage在上下文中調(diào)用createCGImage(outputImage:fromRect :)將返回一個新的CGImage實(shí)例。
  • 3)接下來,使用UIImage(CGImage :)構(gòu)造函數(shù)從新創(chuàng)建的CGImage創(chuàng)建UIImage,而不是像以前一樣直接從CIImage創(chuàng)建。請注意,完成它后不需要像在Objective-C中一樣顯式釋放CGImage。在Swift中,ARC可以自動釋放Core Foundation對象。

構(gòu)建并運(yùn)行,并確保它像以前一樣工作。

OC版本

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //1
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"picture" withExtension:@".png"];
    
    //2
    CIImage *ciImage = [CIImage imageWithContentsOfURL:url];
    
    //3
    CIFilter *ciFilter = [CIFilter filterWithName:@"CISepiaTone"];
    [ciFilter setValue:ciImage forKey:kCIInputImageKey];
    [ciFilter setValue:@(0.5) forKey:kCIInputIntensityKey];
    
    //4
    CIContext *context = [[CIContext alloc] initWithOptions:nil];
    struct CGImage *cgImage = [context createCGImage:ciFilter.outputImage fromRect:ciFilter.outputImage.extent];
    UIImage *image = [[UIImage alloc] initWithCGImage:cgImage];
    self.picImageView.contentMode = UIViewContentModeScaleAspectFit;
    self.picImageView.image = image;
    
}

下面看一下實(shí)現(xiàn)效果

在這個例子中,自己處理CIContext創(chuàng)建并沒有太大的區(qū)別。但是如果您實(shí)現(xiàn)了動態(tài)修改過濾器的能力,那么您將看到設(shè)置上下文這對性能是多么的重要!

后記

本篇主要講述了Core Image的一個簡單說明和示例,感興趣的給個贊或者關(guān)注~~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容