1、App通过CoreGraphics、CoreAnimation、CoreImage等框架的接口调用来触发图形渲染操作
2、CoreGraphics、CoreAnimation、CoreImage等框架将渲染交由OpenGL ES,由OpenGL ES来驱动GPU做渲染,最后显示到屏幕上
3、由于OpenGL ES 是跨平台的,所以在他的实现中,没有任何窗口相关的代码,而是让各自的平台为OpenGL ES提供载体。在iOS中,如果需要使用OpenGL ES,就是通过CoreAnimation提供窗口,让App可以去调用。
三者的概念
CoreGraphics(核心图形)
它是iOS的核心图形库,包含Quartz2D绘图API接口,常用的是point,size,rect等这些图形,都定义在这个框架中,类名以CG开头的都属于CoreGraphics框架,它提供的都是C语言函数接口,是可以在iOS和mac OS 通用的。
iOS系统本身提供了两套绘图的框架,即UIBezierPath 和 Core Graphics。而前者所属UIKit,其实是对Core Graphics框架关于path的进一步封装,所以使用起来比较简单。但是毕竟Core Graphics更接近底层,所以它更加强大。
QuartzCore
Quartz是位于Mac OS X的Drawin核心之上的绘图层,QuartzCore(包含CoreAnimation)框架,是iOS系统的基本渲染框架,是一套基于CoreGraphics的OC语言封装,封装出了基本渲染类CALayer。这个框架感觉不是很清晰,但是看头文件可以发现,它就是CoreAnimation,这个框架头文件只包含了CoreAnimation。
CoreAnimation
Core Animation是一个图形渲染和动画的基础库,是一个复合引擎,职责就是尽可能快地组合屏幕上不同的可视内容,这个内容是被分解成独立的图层,存储在一个叫图层树的体系之中。
1. CoreAnimation是跨平台的,既可以支持IOS,也支持MAC OS。
2. CoreAnimation执行动画是在后台,不会阻塞主线程。
3. CoreAnimation作用在CALayer,不是UIView。
几种常用的Layer
- CAEmitterLayer:CAEmitterLayer是CoreAnimation框架中的粒子发射层,比如:粒子效果的应用和火焰范例。
- CAGradientLayer:CAGradientLayer是用于色彩梯度展示的layer图层,通过CAGradientLayer,我们可以很轻松的创建出有过渡效果的色彩图。
- CAReplicatorLayer:CAReplocatorLayer是拷贝视图容器,我们可以通过它,将其中的子layer进行拷贝,并进行一些差异处理。
- CAShapeLayer:CAShapeLayer是图形layer层,我们可以自定义这个层的形状
- CATextLayer:CATextLayer可以进行文本的绘制
UIView与CALayer
关于动画
CoreAnimation与Core Graphics的使用
CoreAnimation使用
画一条线
//初始化一个线的图层
CAShapeLayer *lineLayer = [CAShapeLayer layer];
//初始化一个描述的路径
UIBezierPath *linePath = [UIBezierPath bezierPath];
//设置线段开始的点
[linePath moveToPoint:beginPoint];
//设置线段结束的点
//这里也可以添加多个点
[linePath addLineToPoint:endPoint];
//设置图层路径
lineLayer.path = linePath.CGPath;
//设置图层的其他属性
lineLayer.lineWidth = lineWidth;
lineLayer.strokeColor = lineColor.CGColor;
lineLayer.fillColor = [UIColor clearColor].CGColor;
Core Graphics的使用
画一条线
//获取当前上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//开始记录路径
CGContextBeginPath(ctx);
//设置开始坐标点
CGContextMoveToPoint(ctx, beginPoint);
//添加坐标点,或者也可以只添加一个坐标点
CGContextAddLineToPoint(ctx, endPoint);
//结束记录路径
CGContextClosePath(ctx);
//设置线段宽度
CGContextSetLineWidth(ctx, lineWidth);
//设置颜色
CGContextSetStrokeColorWithColor(ctx, lineColor.CGColor);
//开始绘制路径
CGContextStrokePath(ctx);
两者比较
1.两种绘制图形的方式:
- 使用Core Animation的 CAShapeLayer图层子类
- 使用Core Graphics
2.Core Graphics是基于cpu进行渲染 ,是使用cpu进行绘制的2d图型库。 Core Animation 是基于GPU进行渲染的,底层实现用到opengl/metal。
3.Core Animation 效率高,流畅,Core Graphics相对效率低。
使用Core Graphics在图片上涂鸦绘制撤销功能
Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。
一、涂鸦绘制流程
UIGraphicsBeginImageContextWithOptions 开始截图的方法
UIGraphicsGetCurrentContext 获取当前上下文
CGContextSetLineWidth 设置画笔宽度
CGContextSetStrokeColor 设置画笔颜色
CGContextSetLineCap 设置LineCap
CGContextMoveToPoint 移动到开始点
CGContextAddLineToPoint 添加line到目的point
CGContextStrokePath 把路径绘制到上下文
UIGraphicsGetImageFromCurrentImageContext 获得UIImage
UIGraphicsEndImageContext 关闭图片上下文
————————————————
二、涂鸦手势移动实现绘制
1.在图片上进行涂鸦,我们需要UIPanGestureRecognizer来实现。UIGestureRecognizer是UIKit框架中的一个基类,用于识别并响应用户的手势操作。
2.实现手势事件
每次手势状态UIGestureRecognizerStateChanged下调用drawLine方法进行,手势结束后存储当前绘制线条的图片。
三、开启橡皮擦功能
橡皮擦功能其实就是CGContextSetBlendMode,将颜色设置了透明色
CGContextSetBlendMode(context, kCGBlendModeClear);
四、撤销功能
撤销功能本质上还是切换图片,将revokeImages存储的图片进行移除操作。
五、设置涂鸦颜色及width
设置涂鸦颜色就是更改strokeColor,width就是更改画笔宽度
CoreImage
Core Image一个图像处理和分析技术,同时也提供了对视频图像实时处理的技术。iOS5中新加入的一个框架,里面提供了强大高效的图像处理功能,用来对基于像素的图像进行操作与分析。还提供了很多强大的滤镜,可以实现你想要的效果,它的处理数据基于CoreGraphics,CoreVideo,和Image I/O框架,既可以使用GPU也可以使用CPU的渲染路径。
其内置了很多强大的滤镜(Filter), 这些Filter 提供了各种各样的效果, 并且还可以通过 滤镜链 将各种效果的 Filter叠加 起来形成强大的自定义效果。
一个 滤镜 是一个对象,有很多输入和输出,并执行一些变换。
一个 滤镜链 是一个链接在一起的滤镜网络,使得一个滤镜的输出可以是另一个滤镜的输入。
CoreImage中三个最重要的对象:
CIImage
保存图像数据的类,是一个不可变对象,它表示一个图像数据。CIImage对象,你可以通过UIImage,图像文件或者像素数据来创建,也可以从一个CIFilter对象的输出来获取。
1. CIImage * ciimage = [[CIImage alloc] initWithImage:image];
2. CIImage * ciimage = [filter outputImage];
CIFilter
表示应用的滤镜,过滤器创建者在内核中定义每块像素图像处理计算,该框架对图片属性进行细节处理的类。它对所有的像素进行操作,用一些键-值设置来决定具体操作的程度。
大家可以去官方文档查看Core Image Filter Reference。
CIFilter * filter = [CIFilter filterWithName:filtername];
[filter setValue:ciimage forKey:kCIInputImageKey];[filter setDefaults];
- CIContex
表示上下文,也是实现对图像处理的具体对象。可以基于CPU或者GPU ,用于绘制渲染,
一个滤镜的基本使用可以分为四步:
- Create a CIImage
- Create a CIContext
- Create a CIFilter
- Get the filter output
创建过滤器时,您可以在其上配置许多依赖于您正在使用的过滤器的属性。过滤器为您提供输出图像作为CIImage ,您可以使用CIContext将其转换为UIImage。
CPU/GPU的不同选择
CIContext上下文是绘制操作发生的地方,创建 CIContext 的方式决定了CoreImage是使用GPU还是CPU来渲染。
CIDetecror
CIDetecror是Core Image框架中提供的一个识别类,包括对人脸、形状、条码、文本的识别。
人脸识别功能不单单可以对人脸进行获取,还可以获取眼睛和嘴等面部特征信息。但是CIDetector不包括面纹编码提取, 只能判断是不是人脸,而不能判断这张人脸是谁的。
app 识别图片
1.在项目中使用图片识别功能,需要导入Vision和CoreML依赖库。
2.导入一个预训练的CoreML模型,主要用于图片分类
3.将识别图片转化为CIImage对象
4.创建一个图像请求处理
5.加载CoreML模型
6.创建一个图片识别请求
7.发送图片请求
import UIKit
import Vision
import CoreML
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 在此处添加图片识别的代码
recognizeImage()
}
func recognizeImage() {
// 获取图片资源
guard let image = UIImage(named: "image.jpg") else {
print("无法读取图片")
return
}
// 将图片转换为 CIImage 对象
guard let ciImage = CIImage(image: image) else {
print("无法将图片转换为 CIImage 对象")
return
}
// 创建一个图像请求处理程序
let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage)
do {
// 加载 CoreML 模型
let model = try VNCoreMLModel(for: YourModel().model)
// 创建一个图像识别请求
let imageRequest = VNCoreMLRequest(model: model) { (request, error) in
// 处理图像识别结果
guard let results = request.results as? [VNClassificationObservation] else {
print("无法获取图像识别结果")
return
}
// 遍历结果并打印
for result in results {
print(result.identifier, result.confidence)
}
}
// 发送图像请求
try imageRequestHandler.perform([imageRequest])
} catch {
print("无法加载模型: \(error)")
}
}
}