CIImage(process img)

core image图像处理和分析技术,用于为core graphics, core video和image I/O框架提供图像操作。它涉及到的主要是3个角色类:

CIImage(process img)_第1张图片

CIFilter: 可变类,用于代表某种特定的处理效果,需要接收至少一个输入并产生一个输出图像

CIImage: 不可变的图像类,可以通过合成数据,或者读取文件,也可以通过获取CIFilter对象的输出来得到CIImage对象

CIContext: 它是core image用来绘制CIFilter所产生的目标图像的地方的对象,这个上下文可以是基于CPU也可以是基于GPU

CIImage(process img)_第2张图片
iOS中使用filter

需要注意的是在第4步中,获取的outputimage只是一份"recipe"(实际是将原始图片处理成目标图片所需要进行的计算),只有在真正需要将目标图片渲染出来的时候(典型的是各Framework中用来在各上下文中将图片绘制出来的带render,drawimage,createimage字样的方法)才会进行最终的渲染,比如第5步中的操作

filter用于标识处理的属性,采用key-value的形式存储,key为常量,value为特定属性类型的值

CIImage(process img)_第3张图片
属性值数据类型

创建core image上下文

CIImage(process img)_第4张图片
上下文为image绘制的目标地

contextWithOptions创建的上下文并没有实时性能,指定CPU还是GPU进行渲染可以使用kCIContextUseSoftwareRenderer属性设置不同的bool值,使用GPU渲染更快,但使用GPU需要先将结果image拷贝到CPU中并转换为比如UIImage之类的对象之后才能被显示出来。

EAGL context类型的CIContext支持实时渲染,且所渲染的图像一直留存在GPU中,通常先需要创建一个EAGL上下文:

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

对于实时绘制,颜色逼真度通常不需要关注,同时也由于其会拖慢整个绘制的性能,可以通过将working color space设置为null以关闭颜色管理

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

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

创建core image对象

CIImage(process img)_第5张图片
从不同image来源创建 core image

hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"];

iOS中,此时hueAdjust的各参数是初始化为默认值的,但OS X不是。hueAdjust有两个输入参数,图像和角度:角度指hue在HSV和HLS颜色空间中的位置,其值变化范围为0到2π,0代表红色,2/3π弧度代表绿色,4/3π代表蓝色。

[hueAdjust setValue: myCIImage forKey: kCIInputImageKey];

[hueAdjust setValue: @2.094f forKey: kCIInputAngleKey];

当然也可以将上述写法替换成

hueAdjust = [CIFilter filterWithName:@"CIHueAdjust"] keysAndValues:

kCIInputImageKey, myCIImage,

kCIInputAngleKey, @2.094f,

nil];

值得提出的是,直到渲染才生成真正的像素可以选择最优的顺序进行计算,比如先上色再缩小图像会比先将图像缩小再上色更费计算。

CIImage(process img)_第6张图片
渲染图像

将结果绘制到屏幕上:

[myContext drawImage:result inRect:destinationRect fromRect:contextRect];

维持线程安全

CIContext和CIImage是不可更改的对象,可在多线程之间共享,但CIFilter是可更改的,所以不可以在多线程之间共享,各线程自己应当创建自己的CIFilter对象。

串联filter

gloom filter通过将图像高亮的部分取消以使图像黯淡

CIFilter *gloom = [CIFilter filterWithName:@"CIGloom"];

[gloom setDefaults];                                        // 1

[gloom setValue: result forKey: kCIInputImageKey];

[gloom setValue: @25.0f forKey: kCIInputRadiusKey];        // 2

[gloom setValue: @0.75f forKey: kCIInputIntensityKey];      // 3

result = [gloom valueForKey: kCIOutputImageKey];            // 4

每2步中,输入半径指定了效果的程度,可在0到100之间变化,默认值为10

3 设置输入密度为0.75,它是一个标量值,在filter输出和原始图像之间指定了线性混合,变化区间为0~1.0, 默认值为1.0

bump distortion filter

CIBumpDistortion Filter在图像中指定点处创建一个凸起。

CIFilter *bumpDistortion = [CIFilter filterWithName:@"CIBumpDistortion"];    // 1

[bumpDistortion setDefaults];                                                // 2

[bumpDistortion setValue: result forKey: kCIInputImageKey];

[bumpDistortion setValue: [CIVector vectorWithX:200 Y:150]

forKey: kCIInputCenterKey];                              // 3

[bumpDistortion setValue: @100.0f forKey: kCIInputRadiusKey];                // 4

[bumpDistortion setValue: @3.0f forKey: kCIInputScaleKey];                  // 5

result = [bumpDistortion valueForKey: kCIOutputImageKey];

4 设置凸起半径为100像素

5 设置输入比例为3,输入比例指定了效果的方向和量,区间为-10~10,默认为-0.5,0代表没有效果,负值代表向外的凸起,正值代表向内的凸起。

切换效果

切换(transition)通常用在幻灯片的切换或者视频中场景的切换,切换效果通常会需要一段时间,并需要设置一个定时器,接下来就是介绍如何设置定时器

CIImage(process img)_第7张图片
由滑雪靴到滑雪者的copy machine 切换

transition filter需要做如下的任务:

1 创建切换需要的ciimage

2 创建并调度一个定时器

3 创建一个CIContext对象

4 创建 CIFilter对象

5 在OS X 中,需要设置filter的默认值

6 设置filter参数

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

8 计算时间

9 应用filter

10 绘制结果

11 重复8-10步走到切换结束

与单纯的图片filter不同的是,切换filter需要在切换过程中的多个时间段内重复绘制效果

在初始的时候启动一个定时器,在drawRect中添加绘制过渡图像的方法,具体做法是以根据时间流逝的长度,取一个参数值,设置CICopyMachineTransition filter的kCIInputTimeKey,并将结果串联到CICrop filter中,将串联的结果绘制出来。同时在每次timeout的时候均setNeedsDisplay

具体可以参考core image program guide>processing images 相应部分

为视频添加Filter

core image和core video协同可以产生很多效果,比如可以使用一个颜色修正filter以修正水吸收红色比绿色和蓝色更快的问题。

具体可以参考core image program guide>processing images 相应部分

你可能感兴趣的:(CIImage(process img))