Core Image框架详细解析(十七) —— 一个简单说明和示例(一)

版本记录

版本号 时间
V1.0 2018.08.08

前言

Core Image是IOS5中新加入的一个框架,里面提供了强大高效的图像处理功能,用来对基于像素的图像进行操作与分析。还提供了很多强大的滤镜,可以实现你想要的效果,下面我们就一起解析一下这个框架。感兴趣的可以参考上面几篇。
1. Core Image框架详细解析(一) —— 基本概览
2. Core Image框架详细解析(二) —— Core Image滤波器参考
3. Core Image框架详细解析(三) —— 关于Core Image
4. Core Image框架详细解析(四) —— Processing Images处理图像(一)
5. Core Image框架详细解析(五) —— Processing Images处理图像(二)
6. Core Image框架详细解析(六) —— 图像中的面部识别Detecting Faces in an Image(一)
7. Core Image框架详细解析(七) —— 自动增强图像 Auto Enhancing Images
8. Core Image框架详细解析(八) —— 查询系统中的过滤器 Querying the System for Filters
9. Core Image框架详细解析(九) —— 子类化CIFilter:自定义效果的配方 Subclassing CIFilter: Recipes for Custom Effects(一)
10. Core Image框架详细解析(十) —— 子类化CIFilter:自定义效果的配方 Subclassing CIFilter: Recipes for Custom Effects(二)
11. Core Image框架详细解析(十一) —— 获得最佳性能 Getting the Best Performance
12. Core Image框架详细解析(十二) —— 使用反馈处理图像 Using Feedback to Process Images
13. Core Image框架详细解析(十三) —— 在写一个自定义滤波器之前你需要知道什么?
14. Core Image框架详细解析(十四) —— 创建自定义滤波器 Creating Custom Filters(一)
15. Core Image框架详细解析(十五) —— 创建自定义滤波器 Creating Custom Filters(二)
16. Core Image框架详细解析(十六) —— 包装和加载图像单元 Packaging and Loading Image Units

简介

Core Image是一个功能强大的框架,可让您轻松地将过滤器应用于图像。 您可以获得各种效果,例如修改振动,色调或曝光。 它可以使用CPU或GPU来处理图像数据,速度非常快 - 足以快速实现视频帧的处理。

Core Image滤镜也可以链接在一起,一次将多种效果应用于图像或视频帧。 多个滤镜组合成一个应用于图像的滤镜。 与通过每个滤波器处理图像(一次一个)相比,这使得它非常有效。

在开始之前,让我们讨论一下Core Image框架中一些最重要的类:

  • CIContextcore image的所有处理都在CIContext中完成。 这有点类似于Core GraphicsOpenGL上下文。
  • CIImage。 该类保存图像数据。 它可以从UIImage,图像文件或像素数据创建。
  • CIFilter。 CIFilter类有一个字典,用于定义它所代表的特定过滤器的属性。 滤波器的示例是振动,颜色反转,裁剪等等。

上面三个类是关于Core Image使用时都要用到的类。


新建工程

首先我们新建立一个OC的工程,然后在sb中拖进去一个imageView控件并设置好约束。

在代码中指定图像并设置填充模式,防止失真。

同样,你也可以建立一个Swift工程,对于展示效果都是一样的,只是使用语言表达方式的不同而已。


Basic Image Filtering - 基本图像滤镜

您只需通过CIFilter运行图像并将其显示在屏幕上即可开始使用。每次要将CIFilter应用于图像时,都需要做四件事:

  • Create a CIImage object - 创建一个CIImage对象。 CIImage有几种初始化方法,包括:CIImage(contentsOfURL :)CIImage(data:)CIImage(CGImage :)CIImage(bitmapData:bytesPerRow:size:format:colorSpace :)等等。您最有可能在大多数时间使用CIImage(contentsOfURL :)
  • Create a CIContext - 创建一个CIContext。 CIContext可以是基于CPU或GPU的。初始化CIContext相对昂贵,因此您可以重复使用它而不是一遍又一遍地创建它。输出CIImage对象时总是需要一个。
  • Create a CIFilter - 创建一个CIFilter。创建过滤器时,您可以在其上配置许多依赖于您正在使用的过滤器的属性。
  • Get the filter output - 获取过滤器输出。过滤器为您提供输出图像作为CIImage - 您可以使用CIContext将其转换为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

让我们逐节讨论这个部分:

  • 1)此行创建一个NSURL对象,该对象包含图像文件的路径。
  • 2)接下来,使用CIImage(contentsOfURL :)构造函数创建CIImage
  • 3)接下来,您将创建CIFilter对象。 CIFilter构造函数采用过滤器的名称,以及指定该过滤器的键和值的字典。每个过滤器都有自己唯一的键和一组有效值。 CISepiaTone过滤器只接受两个值,KCIInputImageKey(一个CIImage)和kCIInputIntensityKey,一个介于0和1之间的浮点值。这里给出的值为0.5。大多数过滤器都有默认值,如果没有提供值,将使用这些值。一个例外是CIImage,必须提供,因为没有默认值。
  • 4)从过滤器中取出CIImage就像使用outputImage属性一样简单。一旦有了输出CIImage,就需要将它转换为UIImageUIImage(CIImage :)构造函数从CIImage创建UIImage。将它转换为UIImage后,只需将其显示在之前添加的图像视图中即可。

构建并运行项目,您将看到通过棕褐色调过滤器过滤的图像。

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

运行并查看效果,如下所示:


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

在你继续之前,你应该知道一个优化。

我之前提到你需要一个CIContext来应用一个CIFilter,但在上面的例子中没有提到这个对象。 事实证明,UIImage(CIImage :)构造函数可以为您完成所有工作。 它创建一个CIContext并使用它来执行过滤图像的工作。 这使得使用Core Image API非常容易。

有一个主要缺点 - 它每次使用时都会创建一个新的CIContext。 CIContext实例旨在可重用以提高性能。 如果您想使用滑块更新过滤器值,就像您在本教程中所做的那样,每次更改过滤器时创建一个新的CIContext都会太慢。

我们这样做吧。 从添加到viewDidLoad()的代码中删除第4步,并将其替换为以下内容:

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

再说一次,让我们逐节讨论。

  • 1)在这里,您可以设置CIContext对象并使用它来绘制CGImageCIContext(options :)构造函数采用NSDictionary,它指定颜色格式等选项,或上下文是否应在CPU或GPU上运行。对于这个app,默认值是正常的,所以你传递nil为该参数。
  • 2)使用提供的CIImage在上下文中调用createCGImage(outputImage:fromRect :)将返回一个新的CGImage实例。
  • 3)接下来,使用UIImage(CGImage :)构造函数从新创建的CGImage创建UIImage,而不是像以前一样直接从CIImage创建。请注意,完成它后不需要像在Objective-C中一样显式释放CGImage。在Swift中,ARC可以自动释放Core Foundation对象。

构建并运行,并确保它像以前一样工作。

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;
    
}

下面看一下实现效果

在这个例子中,自己处理CIContext创建并没有太大的区别。但是如果您实现了动态修改过滤器的能力,那么您将看到设置上下文这对性能是多么的重要!

后记

本篇主要讲述了Core Image的一个简单说明和示例,感兴趣的给个赞或者关注~~~~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容