Core Image编程指南

在iOS和MAC上,Core Image有三个类支持图片处理:

1.    CIFilter:一个可变的对象代表一个影响。一个滤波对象至少有一个输入参数并且产生一个输出图片。

2.    CIImage:是一个不可变的对象,代表一个图片。你可以同步图片数据或者从文件中获取或者是另一个CIFilter对象的输出。

3.    CIContext:CoreImage通过这个对象将滤波产生的结果画出来。一个Core Image上下文可以基于CPU或者是GPU。

 

Overview

使用Core Image时需要在项目中加入框架CoreImage.framework。并且在源文件中引入相应的头文件<CoreImage/CoreImage.h>.

 

Listing 1-1 在一个图片上应用滤波的基本步骤


1.    创建一个CIContext对象。

2.    创建一个CIImage对象。

3.    创建一个滤波对象并设置它的输入参数。

4.    获得输出图片。这个输出图片是怎样产生图片的一个方案。图片并没有被渲染。

5.    渲染CIImage为一个Core Graphics图片,来准备展示或者存储到文件。

Note:一些Core Image滤波生成无限大的图片,例如在CICategoryTileEffect目录中的那些filters.在这种情况下,在渲染之前要不需要裁剪图片,要不指定一个有限大小的矩形。


创建一个CoreImage Context

为了渲染图片,需要创建一个Core Image Context,然后使用这个上下文来绘制输出图片。一个上下文代表一个绘制目的地。这个目的地决定Core Image使用GPU还是CPU来渲染。下面的表格指明指定平台的不同方法来渲染。



创建一个CoreImage Context当你不需要实时的性能

CIContext *context = [CIContextcontextWithOptions:nil];

这个方法可以使用GPU,也可以使用CPU进行渲染。指明使用哪个,可以提供一个options字典,增加关键字kCIContextUseSoftwareRender,并使用合适的布尔值赋值。CPU比GPU渲染要慢。但是在GPU渲染时,结果图片只有当被拷贝到CPU内存并且转换为例如UIImage这种图片类型才会被展示出来。

 

创建一个CoreImage Context当需要实时的性能

如果你的APP需要实时图片处理,那么你应该用EAGL上下文来创建一个CIContext对象,而不是使用contextWithOptions:并且指明使用GPU。这样做的好处是渲染的图片保存在GPU中并且不会复制到CPU内存中。首先你需要穿件一个EAGL上下文

EAGLContext*myEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]

然后使用方法contextWithEAGLContext:创建一个CIContext对象。

你应该关掉颜色管理通过为工作的颜色空间提供null值。颜色管理会降低性能。当需要颜色保真的时候,你需要使用颜色管理。但是在一个实时的APP里,颜色保真度往往是不care的。

NSDictionary*options = @{kCIContextWorkingColorSpace:[NSNull null]};

CIContext*myContext = [CIContext contextWithEAGLContext:myEAGLContext options:options];

 

创建一个CIImage对象

Core Image filter处理Core Image 图片。以下表格列出了创建CIImage对象的方法。你使用的方法依赖于图片源。记住CIImage对象是一个真正的图片的recipe。Core Image不会真正的产生任何像素直到被调用到目的地去渲染结果



创建一个滤波对象并且设置值

filterWithName:方法创建一个类型为指定名字参数的滤波器。名字参数是一个字符串,这个值必须匹配内建滤波器的名字。可以在Core Image Filter Reference中找到所有的内建滤波器。

在iOS中,当调用filterWithName:方法时,一个滤波器的输入值会被设置成默认值。

hueAdjust = [CIFilterfilterWithName:@”CIHueAdjust”];

//这个滤波器有两个参数,一个是输入图片,一个是输入角度

[hueAdjustsetValue:myCIImage forKey:kCIInputImageKey];

[hueAdjustsetValue:@2.094f forKey:kCIInputAngleKey];

有一个更紧凑的方式创建滤波器并且设置值:

hueAdjust=[CIFilter  filterWithName:@”CIHueAdjust”

withInputParameters:@{kCIInputImageKey:myCIImage,kCIIputAngleKey:@2.094f}];

 

获得输出图片

通过检索outputImage的值来获得输出图片。

CIImage *result =[hueAdjust valueForKey:kCIOutputImageKey];

Core Image不会做任何图片处理直到调用真正的图片渲染方法时才会处理。当你请求一个输出图片,Core Image收集产生一个输出图片的计算结果并且存储这些计算结果(这就是所谓的图片recipe)在一个CIImage对象中。

推迟处理直到渲染时间是的Core Image快并且高效。在渲染的时候,Core Image可以看到是否有多个滤波器被应用在一张图片上。如果是这样,它会自动连接多个recipes到一个操作中,也就说一个像素仅处理一次。而且还会自动权衡应用滤波的顺序来使得处理更高效(比如颜色调整和图片大小调整,相反顺序处理起来会更加高效)。

 

渲染输出图片

渲染结果输出图片会触发处理器的操作:GPU或者CPU。这取决于定义的上下文。以下方法可以用来渲染图片:


保持线程安全

CIContext和CIImage对象是不可变的,这意味着他们可以在很多线程中被安全的共享。多个线程可以使用同一个GPU或者CPU的CIContext对象来渲染CIImage对象。然而CIFilter并不是这样的,CIFilter是可变的。一个CIFilter对象不能在多个线程中共享。如果 你的app是多线程的,每个线程必须创建它自己的CIFilter对象。否则你的app将不会按预期的样子执行。

 

连锁滤波

上一个滤波的输出是当前滤波的输入:


result是list1-1中得到的输出图片,此时作为新的滤波器的输入图片。在iOS中可以不用写1处的代码,因为当设置滤波时会自动设置,在OSX系统中需要显示设置。

 

应用一个滤波到VIDEO

Core Image和Core Video可以一起工作完成很多效果。以下步骤可以应用一个滤波到video使用Core video在OSX上。

1.    使用NSView的子类创建一个video的view


2.   当你用一帧初始化一个view时,可以创建一个CIFilter对象并且设置默认值


3.    设置滤波器的输入参数,除了输入图片

4.    每次渲染一帧时,你需要设置输入图片并且绘制输出图片。你的renderCurrentFrame方法如下。为避免篡改,在绘制输出时,这个例子使用完整的坐标系



使用转换效果

转换被典型的使用在滑动展示图片或者在video中从一个场景切换到另一个场景。这些效果需要每次渲染,所以需要设置一个定时器。这一部分的内容主要介绍如何设置一个定时器。你将学会如何通过设置并应用CICopyMachine滤波到两个静态的图片上来做这件事情。转换滤波需要以下任务:

1.    创建CIImage对象。

2.    设置并安排一个定时器。

3.    创建一个CIContext对象

4.    创建一个CIFilter对象。

5.    在OSX上,需要为滤波器设置默认值。(iOS不需要)

6.    设置滤波器的参数

7.    设置需要处理的源和目标图片

8.    计算时间

9.    应用滤波

10.  绘制结果

11.  重复8-10,直到转换完成。

awakeFromNib方法,获得两个图片并且把他们设置成源图片和目的图片。使用NSTimer类,设置每1/30分钟重复。注意变量thumbnailWidth和thumbnailHeight,用来限制渲染图片到view



设置转换滤波器


drawRect方法设置一个与视图大小相等的矩形。并且设置一个浮点数作为渲染时间。


imageForTransition方法基于渲染时间指出哪个是源图片哪个是目标图片。它被设置成容许重复的前后转换。如果你的app应用一个转换但是没有循环,那么将不需要if-else结构。

函数流程设置inputTime值传递给这个方法。它应用转换,传递图片从转换到crop 滤波,crop可以保证输出图片适合视图大小。函数返回截取后的转换图片给drawRect函数绘制图片。



每当时间到时,视图展示应该被更新



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值