一.什么是Core Image
Core Image是一种图像处理和分析技术,旨在为静止和视频图像提供近乎实时的处理。它使用GPU或CPU呈现路径,对核心图形、核心视频和图像I/O框架中的图像数据类型进行操作。Core Image通过提供一个易于使用的应用程序编程接口(API)来隐藏底层图形处理的细节。您不需要了解OpenGL、OpenGL ES或Metal的细节来利用GPU的能力,也不需要了解Grand Central Dispatch (GCD)来获得多核处理的好处。Core Image为您处理细节。
二.功能
- 访问内置的图像处理过滤器
- 特征检测能力
- 支持自动图像增强
- 将多个过滤器链接在一起以创建自定义效果的能力
- 支持创建自定义过滤器,运行在GPU上
- 基于反馈的图像处理能力
Core Image在处理、分析图片上是非常高效和易用的
Core Image可以分析图像的质量,并提供一组具有最佳设置的过滤器,用于调整色调、对比度和色调颜色,以及校正诸如红眼之类的flash伪影。它通过您部分的一个方法调用来完成所有这些工作。
Core Image可以在静止图像中检测人脸特征,并在视频图像中随着时间的推移进行跟踪。知道人脸的位置可以帮助您确定在何处放置小插曲或应用其他特殊的过滤器。
查询Core Image以获得过滤器及其属性列表
Core Image有其过滤器的“内置”参考文档。您可以查询系统以确定哪些过滤器可用。然后,对于每个过滤器,您可以检索包含其属性的字典,例如其输入参数、默认参数值、最小值和最大值、显示名称等等。
核心图像可以实现实时视频性能
如果你的应用程序需要实时处理视频,你可以做几件事来优化性能。
使用图像累加器支持基于反馈的处理
CIImageAccumulator类是为高效的基于反馈的图像处理而设计的,如果您的应用程序需要对动态系统进行图像处理,您可能会发现它很有用。
创建和分发自定义内核和过滤器
如果没有一个内置的过滤器适合您的需要,即使链接在一起,也可以考虑创建一个自定义过滤器。您需要理解内核——在像素级运行的程序,因为它们位于每个过滤器的核心。
三.图像处理
图像处理需要用到过滤器——图像过滤器是一种逐像素检查输入图像并通过算法应用某种效果来生成输出图像的软件。在CoreImage中,图像处理依赖于CIFilter和CIImage类,它们描述过滤器及其输入和输出。要应用过滤器并显示或导出结果,可以使用Core Image和其他系统框架之间的集成,或者使用CIContext类创建自己的呈现工作流。本章介绍了使用这些类应用过滤器和呈现结果的关键概念。
- 在一个应用程序中,使用Core Image进行图像处理有许多方法。
@property (nonatomic, strong) UIImageView *theImageViewBack;
- (void)viewDidLoad
{
[super viewDidLoad];
self.theImageViewBack = [[UIImageView alloc]init];
self.theImageViewBack.frame = CGRectMake(kScreenWidth/2.0 - 100, 100, 200, 300);
self.theImageViewBack.image = [UIImage imageNamed:@"beauty2.jpg"];
[self.view addSubview:self.theImageViewBack];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//filter相关
CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"];
[filter setValue:@0.8 forKey:kCIInputIntensityKey];
UIImage *img = [UIImage imageNamed:@"beauty2.jpg"];
CIImage *ciImage = [[CIImage alloc] initWithImage:img];
[filter setValue:ciImage forKey:kCIInputImageKey];
CIImage *outImage = filter.outputImage;
//输出图片
CIContext *context = [CIContext context];
CGImageRef cgImage = [context createCGImage:outImage
fromRect:[outImage extent]];
UIImage *retImage = [UIImage imageWithCGImage:cgImage];
self.theImageViewBack.image = retImage;
}
-
Images are the Input and Output of Filters
CoreImage过滤器处理并生成CoreImage图像。CIImage实例是一个image的不可变对象。这些对象并不直接表示图像位图数据——相反,CIImage对象是生成image的“配方”。一种方法可能要求从文件中加载图像;另一个可能表示来自过滤器的输出,或者来自filter链。Core Image只在您请求将图像呈现为显示或输出时才执行这些配方。要应用过滤器,创建一个或多个CIImage对象来表示过滤器要处理的图像,并将它们分配给过滤器的输入参数(例如kCIInputImageKey)。你可以创建一个Core Image图像对象从几乎任何来源的图像数据,包括:
- url引用要加载的图像文件或包含图像文件数据的NSData对象
- Quartz2D、UIKit或AppKit图像表示(CGImageRef、UIImage或NSBitmapImageRep对象)
- Metal,OpenGL,或OpenGL ES纹理
- CoreVideo image or pixel buffers(CVImageBufferRef或CVPixelBufferRef)
- 在进程之间共享图像数据的IOSurfaceRef对象
- 内存中的图像位图数据(指向此类数据的指针,或按需提供数据的CIImageProvider对象)
因为CIImage对象描述了如何生成图像(而不是包含图像数据),所以它还可以表示过滤器输出。当访问CIFilter对象的outputImage属性时,Core Image只标识和存储执行过滤器所需的步骤。只有当您请求将图像呈现为显示或输出时,才会执行这些步骤。您可以使用CIContextrender或draw方法隐式地请求呈现,方法是使用使用Core image的许多系统框架中的一个来显示图像(请参阅与其他框架的集成)。
-
filter描述图像处理效果
CIFilter类的实例是一个可变对象,表示图像处理效果和控制该效果行为的任何参数。要使用过滤器,您需要创建一个CIFilter对象,设置它的输入参数,然后访问它的输出图像。调用filterWithName:初始化器,使用系统已知的过滤器的名称实例化过滤器对象。大多数过滤器都有一个或多个输入参数,允许您控制如何进行处理。每个输入参数都有一个属性类来指定它的数据类型,比如NSNumber。输入参数可以选择具有其他属性,例如其默认值、允许的最小值和最大值、参数的显示名称以及CIFilter类引用中描述的其他属性。例如,CIColorMonochrome过滤器有三个输入参数——要处理的图像、单色和颜色强度。
filter参数定义为键值对;要处理参数,通常使用valueForKey:和setValue:forKey:方法或其他基于键值编码的特性(如Core Animation)。键是标识属性的常量,值是与键关联的设置。Core Image属性值通常使用属性值数据类型中列出的数据类型之一。
重要提示:CIFilter对象是可变的,因此不能在不同的线程之间安全地共享它们。每个线程必须创建自己的CIFilter对象。但是,过滤器的输入和输出CIImage对象是不可变的,因此可以安全地在线程之间传递。 -
用于复杂效果的链接filter
每个核心图像过滤器都会生成一个输出CIImage对象,因此可以使用该对象作为另一个过滤器的输入。例如,图1-1所示的过滤器序列对图像应用颜色效果,然后添加辉光效果,最后从结果中裁剪出一部分。
-
使用特殊的filter,可以获得更多的效果
大多数内置的核心图像过滤器对主输入图像(可能与影响处理的其他输入图像一起)进行操作,并创建单个输出图像。但是,您可以使用其他几种类型来创建有趣的效果,或者与其他过滤器结合使用来生成更复杂的工作流。一个混合的filter根据预设的公式来组合两个图像。例如:
CISourceInCompositing过滤器将图像组合在一起,这样只有两个输入图像中不透明的区域在输出图像中可见。
CIMultiplyBlendMode滤波器将两幅图像的像素颜色相乘,生成一个变暗的输出图像。
您可以通过对每个输入图像应用几何调整,在合成它们之前对它们进行排列。generator filter不接受输入图像。相反,这些过滤器使用其他输入参数从零开始创建新图像。一些生成器生成的输出可以单独使用,而另一些生成器可以组合在过滤器链中生成更有趣的图像。一些例子从内置的Core Image过滤器包括:
- 过滤器如CIQRCodeGenerator和CICode128BarcodeGenerator生成编码指定输入数据的条形码图像。
- 过滤器如CIConstantColorGenerator、CICheckerboardGenerator和CILinearGradient从指定的颜色生成简单的过程图像。您可以将它们与其他过滤器结合使用,以获得有趣的效果——例如,CIRadialGradient过滤器可以创建一个掩模,用于CIMaskedVariableBlur过滤器。
- 像CILenticularHaloGenerator和CISunbeamsGenerator这样的过滤器可以创建独立的视觉效果——将它们与合成过滤器结合起来,为图像添加特殊效果。
reduction filter对输入图像进行操作,但是它的输出描述有关输入图像的信息,而不是传统意义上的创建输出图像。例如:
- CIAreaMaximum过滤器输出一个颜色值,表示图像指定区域中所有像素颜色中最亮的颜色。
- CIAreaHistogram过滤器输出关于图像指定区域中每个强度值的像素数的信息。
所有核心图像过滤器都必须生成一个CIImage对象作为它们的输出,因此reduce filter生成的信息仍然是一个图像。但是,通常不显示这些图像,而是从单像素或单行图像中读取颜色值,或者将它们用作其他过滤器的输入。
transition filter需要两个输入图像和它们之间的不同其输出独立variable-typically,这个变量是时间,所以您可以使用一个转换过滤器创建一个动画,始于一个图像,在另一个结束,进行从一个到另一个使用一个有趣的视觉效果。Core Image提供了几个内置的转换过滤器,包括:
- CIDissolveTransition过滤器产生一个简单的交叉溶解,从一个图像到另一个图像的淡入。
- CICopyMachineTransition过滤器模拟影印机,将一束强光扫过一幅图像以显示另一幅图像。
-
与其他框架集成
Core Image与iOS、macOS和tvOS中的其他一些技术进行交互。由于这种紧密的集成,您可以使用Core Image轻松地向应用程序的用户界面中的游戏、视频或图像添加视觉效果,而不需要构建复杂的呈现代码。下面的部分将介绍在应用程序中使用Core Image的几种常见方法,以及系统框架为每种方法提供的便利。在UIKit和AppKit中,导入Core Image框架即可处理静止图像
UIKit和AppKit提供了向静态图像添加核心图像处理的简单方法,无论这些图像是出现在应用程序的UI中还是作为其工作流的一部分。例如:- 旅游应用程序可能会在列表中显示目的地的库存照片,然后对这些照片应用过滤器,为每个目的地的详细页面创建一个微妙的背景。
- 社交应用程序可能会对用户头像图片应用过滤器,以显示每个帖子的情绪。
- 摄影应用程序可能允许用户在捕捉图像时使用过滤器自定义图像,或者提供一个照片应用程序扩展,用于在用户的照片库中添加效果
Processing Video with AV Foundation
AVFoundation框架提供了许多用于处理视频和音频内容的高级实用程序。其中一个是AVVideoComposition类,您可以使用它将视频和音频轨道合并或编辑成一个演示文稿。您可以使用AVVideoComposition对象在回放或导出期间对视频的每一帧应用核心图像过滤器 -
使用Core Image Context构建自己的工作流
当您使用上一节中列出的技术应用Core Image过滤器时,这些框架会自动管理Core Image用于处理图像和呈现结果的底层资源。这种方法既最大化了这些工作流的性能,又使它们更容易设置。然而,在某些情况下,使用CIContext类自己管理这些资源更为谨慎。通过直接管理核心映像上下文,您可以精确地控制应用程序的性能特征,或者将核心映像与底层呈现技术集成。Core Image Context表示执行过滤器和生成图像所需的CPU或GPU计算技术、资源和设置。有几种上下文可供选择,所以您应该选择最适合您的应用程序的工作流和您可能正在使用的其他技术的选项。下面讨论一些常见的场景;
重点:Core Image Context是管理大量资源和状态的重量级对象。重复创建和销毁上下文会带来很大的性能成本,因此,如果您计划执行多个图像处理操作,请尽早创建上下文并将其存储起来,以便将来重用。
Rendering with an Automatic Context 自定义context
如果您没有限制您的应用程序如何与其他图形技术交互,创建一个Core Image Context是很简单的:只需使用基本的init或initWithOptions: initializer。当您这样做时,Core Image会自动在内部管理资源,根据当前设备和您指定的任何选项选择适当的或最佳的可用CPU或GPU呈现技术。这种方法非常适合于将处理后的图像呈现到文件中(例如,使用writeJPEGRepresentationOfImage:toURL:colorSpace:options:error: method)。注意:没有显式声明目标的context不能使用drawImage:inRect:fromRect:方法,因为该方法的行为随使用的呈现目的地的不同而变化。相反,使用名称以render或create开头的CIContext方法来指定显式目的地。
如果您打算实时呈现核心图像,那么在使用这种方法时要小心,即使过滤器参数的变化具有动画效果、产生动画转换效果、或处理每秒已经呈现多次的视频或其他可视内容。尽管使用这种方法创建的CIContext对象可以使用GPU自动呈现,但是呈现呈现的结果可能需要在CPU和GPU内存之间进行昂贵的复制操作。
Real-Time Rendering with Metal
四.人脸识别
Core Image可以分析和发现图像中的人脸。它执行人脸检测,而不是识别。人脸检测是对包含人脸特征的矩形的识别,而人脸识别是对特定人脸的识别(John, Mary等)。Core Image检测到人脸后,可以提供人脸特征的信息,比如眼睛和嘴巴的位置。它还可以跟踪视频中人脸的位置。
知道人脸在图像中的位置,可以执行其他操作,比如裁剪或调整人脸的图像质量(色调平衡、红眼校正等)。你也可以对人脸进行其他有趣的操作
- 检测人脸
CIContext *context = [CIContext context];
NSDictionary *opts = @{
CIDetectorAccuracy:CIDetectorAccuracyHigh
};
CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
context:context options:opts];
UIImage *img = [UIImage imageNamed:@"beauty2.jpg"];
CIImage *ciImage = [[CIImage alloc] initWithImage:img];
opts = @{
CIDetectorImageOrientation:[ciImage.properties valueForKey:CIDetectorImageOrientation]
};
NSArray *features = [detector featuresInImage:ciImage options:opts];
NSLog(@"%@",features);
- 获取人脸信息详情
包括:眼睛的位置, 嘴巴的位置, 在视频中跟踪ID和位置
for (CIFaceFeature *f in features) {
NSLog(@"%@", NSStringFromRect(f.bounds));
}
五.自动增强滤镜
Core Image的自动增强特性分析图像的直方图、人脸区域内容和元数据属性。然后,它返回一个CIFilter对象数组,这些对象的输入参数已经被设置为将改进所分析的图像的值。
- Auto Enhancement Filters 自动增强滤镜
下图是一些自动增强滤镜,这些滤镜弥补了在照片中发现的一些最常见的问题.
- 使用自动增强滤镜
NSDictionary *options = @{ CIDetectorImageOrientation :
[[image properties] valueForKey:kCGImagePropertyOrientation] };
NSArray *adjustments = [myImage autoAdjustmentFiltersWithOptions:options];
for (CIFilter *filter in adjustments) {
[filter setValue:myImage forKey:kCIInputImageKey];
myImage = filter.outputImage;
}
六.查询系统中的滤镜
Core Image提供了一些方法,让您可以查询系统中可用的内置过滤器以及关于每个过滤器的相关信息——显示名称、输入参数、参数类型、默认值等等。查询系统为您提供关于可用过滤器的最新信息。如果您的应用程序支持让用户选择和设置过滤器,您可以在为过滤器创建用户界面时使用这些信息。
- Getting a List of Filters and Attributes 获取滤镜和属性的数组
1.使用filterNamesInCategory:
和[filterNamesInCategories:]
方法来发现哪些滤镜是可用的。滤镜被分类以使列表更易于管理。如果您知道某个滤镜类别,那么您可以通过调用filterNamesInCategory
方法找到该类别的可用滤镜.
2.如果希望为类别列表找到所有可用的滤镜,可以调用filternamesincategors:
方法,从表中列出的类别常量中提供一个类别常量数组。该方法返回一个NSArray对象,其中填充了每个类别的滤镜名称。您可以通过提供nil而不是类别常量数组来获得所有类别的所有过滤器列表。
- Building a Dictionary of Filters 构建滤镜字典
如果您的应用程序提供了一个用户界面,它可以参考滤镜字典来创建和更新用户界面。例如,筛选布尔值的属性需要复选框或类似的用户界面元素,而在一个范围内不断变化的属性可以使用滑块。您可以使用最大值和最小值作为文本标签的基础。默认属性设置将指示用户界面中的初始设置。
滤镜名称和属性提供了构建用户界面所需的所有信息,该界面允许用户选择筛选器并控制其输入参数。过滤器的属性告诉您过滤器有多少输入参数、参数名称、数据类型以及最小值、最大值和默认值。
七.子类化CIFilter:定制效果的秘诀
您可以使用一个图像滤镜的输出作为另一个图像滤镜的输入来创建自定义效果,可以将任意多个过滤器链接在一起。当您以这种方式创建希望多次使用的效果时,请考虑将CIFilter子类化以将效果封装为过滤器。
本章展示了Core Image子类CIFilter如何创建CIColorInvert滤镜。然后描述了将各种滤镜链接在一起以实现有趣效果的方法。通过遵循子类化CIFilter中的子类化过程来创建CIColorInvert滤镜,您应该能够根据本章中的秘诀创建滤镜,或者大胆地创建Core Image提供的内置滤镜的有趣组合。
- Subclassing CIFilter to Create the CIColorInvert Filter 子类化滤镜并创建一个CIColorInvert Filter
当您子类化CIFilter时,您可以通过使用预设值对现有滤镜进行编码或将它们链接在一起来修改它们。Core Image使用这种技术实现了它的一些内置过滤器。
#import
@interface CIColorInvert: CIFilter {
CIImage *_inputImage;
}
//您必须在每个输入参数名称前面加上输入前缀input,例如inputImage。
//Override the setDefaults method(如果自己赋值的话,可以不用写)
//Override the outputImage method
@property (strong, nonatomic) CIImage *inputImage;
@end
@implementation CIColorInvert
- (CIImage *) outputImage
{
CIFilter *filter = [CIFilter filterWithName:@"CIColorMatrix"
withInputParameters:
@{
kCIInputImageKey: _inputImage,
@"inputRVector": [CIVector vectorWithX:-1 Y:0 Z:0],
@"inputGVector": [CIVector vectorWithX:0 Y:-1 Z:0],
@"inputBVector": [CIVector vectorWithX:0 Y:0 Z:-1],
@"inputBiasVector": [CIVector vectorWithX:1 Y:1 Z:1],
}];
return filter.outputImage;
}
@end
-
Chroma Key Filter Recipe 色度键滤镜
创建色度键滤镜的3个步骤:
1.创建一个数据立方体映射,该数据映射您想要删除的颜色值,使它们是透明的(alpha值是0.0)。
2.使用CIColorCube filter和cube map从源图像中删除色度键颜色。
3.使用CISourceOverCompositing滤镜将经过处理的源图像混合到背景图像上
太复杂了,请看原文章
https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_filer_recipes/ci_filter_recipes.html#//apple_ref/doc/uid/TP30001185-CH4-SW1
八.Getting the Best Performance 获得最佳表现
Core Image为创建图像、上下文和呈现内容提供了许多选项。你如何选择完成一项任务取决于:
您的应用程序需要多久执行一次任务
无论您的应用程序是否与静止或视频图像工作
是否需要支持实时处理或分析
颜色保真度对用户有多重要
您应该仔细阅读性能最佳实践,以确保您的应用程序尽可能高效地运行。
- Performance Best Practices 性能最佳实践
为获得最佳表现,请遵循以下实践:
1.不要每次渲染时都创建CIContext对象。
2.上下文存储了大量的状态信息;重用它们更有效。
3.评估你的应用程序是否需要颜色管理。除非你需要,否则不要使用它。看看你的应用程序需要颜色管理吗?
4.使用GPU上下文渲染CIImage对象时避免使用核心动画。
5.如果需要同时使用两者,可以将两者设置为使用CPU。
6.确保图像不超过CPU和GPU的限制。
7.CIContext对象的图像大小限制取决于核心图像是使用CPU还是GPU。用输入和输出方法检查极限。
8.尽可能使用较小的图像。
9.性能随输出像素的数量而变化。您可以将核心图像呈现到较小的视图、纹理或framebuffer中。允许核心动画高档显示大小。
10.使用核心图形或图像I/O函数来裁剪或向下采样,例如CGImageCreateWithImageInRect或CGImageSourceCreateThumbnailAtIndex函数。
11.UIImageView类最适合于静态图像。
12.如果您的应用程序需要获得最佳性能,请使用较低级别的api。
13.避免不必要的纹理传输之间的CPU和GPU。
14.在应用内容缩放因子之前,呈现为与源图像大小相同的矩形。
15.考虑使用更简单的过滤器,可以产生类似于算法过滤器的结果。
16.例如,CIColorCube可以产生类似顺帕酮的输出,而且效率更高。
17.利用iOS 6.0及更高版本对YUV映像的支持。
注:相机像素缓冲器是天生的YUV,但大多数图像处理算法期望RBGA数据。两者之间的转换是有成本的。Core Image支持从CVPixelBuffer对象读取YUB并应用适当的颜色转换。
@(kCVPixelFormatType_420YpCbCr88iPlanarFullRange) };
- Does Your App Need Color Management?
默认情况下,Core Image应用光线性颜色空间中的所有过滤器。这提供了最准确和一致的结果。
sRGB与sRGB之间的转换增加了滤波的复杂度,需要Core Image应用这些方程:
rgb = mix(rgb.0.0774, pow(rgb*0.9479 + 0.05213, 2.4), step(0.04045, rgb))
rgb = mix(rgb12.92, pow(rgb*0.4167) * 1.055 - 0.055, step(0.00313, rgb))
考虑禁用颜色管理,如果:
1.您的应用程序需要绝对最高的性能。
2.用户不会注意到夸大操作后的质量差异。
若要禁用颜色管理,请将kCIImageColorSpace键设置为null。如果您正在使用EAGL上下文,那么在创建EAGL上下文时也要将上下文颜色空间设置为null。参见使用核心映像上下文构建您自己的工作流。
九.Using Feedback to Process Images 根据反馈处理图像
CIImageAccumulator类非常适合于基于反馈的处理。顾名思义,它会随着时间累积图像数据。本章展示了如何使用CIImageAccumulator对象来实现一个简单的绘画应用程序MicroPaint,该应用程序允许用户在画布上画画来创建类似于下图所示的图像。
[站外图片上传中...(image-ad2f41-1554703940965)]
“image”以空白画布开始。MicroPaint使用一个图像累加器来收集用户使用的油漆。当用户单击Clear时,MicroPaint将图像累加器重置为白色画布。颜色允许用户改变颜料的颜色。用户可以使用滑块更改画笔大小。
- Set Up the Interface for the MicroPaint App
太长 0.0 用的时候看
https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_feedback_based/ci_feedback_based.html#//apple_ref/doc/uid/TP30001185-CH5-SW2
十.What You Need to Know Before Writing a Custom Filter
Core Image支持编写自定义过滤器。自定义过滤器是编写一个称为内核的例程的过滤器,它指定要对每个源图像像素执行的计算。如果您计划使用内置的核心图像过滤器,无论是按原样使用还是通过子类化它们,您都不需要阅读本章。如果您计划编写一个自定义过滤器,您应该阅读本章,以便理解自定义过滤器中的处理路径和组件。阅读本章后,您可以了解如何在创建自定义过滤器中编写过滤器。如果您对打包用于分发的自定义过滤器感兴趣,还应该阅读打包和加载图像单元。
你懂得
https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_advanced_concepts/ci.advanced_concepts.html#//apple_ref/doc/uid/TP30001185-CH9-SW1
十一.Creating Custom Filters
如果Core Image提供的过滤器没有提供您需要的功能,您可以编写自己的滤镜。您可以将滤镜作为应用程序项目的一部分,或者(仅在macOS中)将一个或多个滤镜打包为独立的映像单元。图像单元使用NSBundle类,并允许应用程序托管外部插件滤镜。
- Expressing Image Processing Operations in Core Image:解释Core Image是怎样处理图像的
Core Image的工作原理是这样的:将内核(即每个像素的处理例程)编写为一个计算,其中使用返回到内核输入图像的对应像素的逆映射来表示输出像素。虽然您可以用这种方法表示大多数像素计算—有些比其他方法更自然—但对于某些图像处理操作,即使不是不可能,也很难做到这一点。在编写过滤器之前,您可能需要考虑图像处理操作是否可以用Core image表示。例如,计算直方图很难描述为到源图像的反向映射。
- Creating a Custom Filter: 创建一个自定义滤镜
1.本节将展示如何创建具有Objective-C部分和内核部分的核心图像过滤器。按照本节中的步骤,您将创建一个CPU可执行的过滤器。您可以按照打包和加载图像单元中的说明将此过滤器以及其他过滤器打包为图像单元。或者,您可以简单地在您自己的应用程序中使用过滤器。
2.Core Image提供了三种基于内核的过滤器:颜色过滤器、翘曲过滤器和通用过滤器。通用过滤器包括一个GPU内核例程,可以修改像素颜色和像素位置。但是,如果您正在设计一个只修改像素颜色的过滤器,或者在不修改像素的情况下更改图像几何形状,那么创建一个颜色或翘曲过滤器可以让Core image在各种iOS和Mac硬件上提供更好的过滤器性能。
3.本节中的一般过滤器假设感兴趣的区域(ROI)与定义的域一致。如果您想要为这个假设不成立的过滤器编写代码,请确保您还阅读了提供ROI函数的代码。在创建自己的自定义过滤器之前,请确保理解核心图像坐标空间。参见构建过滤器字典。