版本记录
版本号 | 时间 |
---|---|
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框架中一些最重要的类:
-
CIContext
。core image
的所有处理都在CIContext
中完成。 这有点类似于Core Graphics
或OpenGL
上下文。 -
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
,就需要将它转换为UIImage
。UIImage(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
对象并使用它来绘制CGImage
。CIContext(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的一个简单说明和示例,感兴趣的给个赞或者关注~~~~