前言
多媒体技能 包含 视觉图形处理
、音频视频处理
、XR技能
(AR、VR)等。都是风趣且富有含金量的技能实践方向。
本篇文章是 iOS 视觉图形处理
技能中心结构简介,为咱们快速了解 iOS 视觉图形 技能,以便于在项目实战中进行技能选型、为提高自己在图形学上的技能才能指明方向,为后期咱们在图形学方面的项目实践在某一个点的深入埋下伏笔。
一、iOS图画处理相关结构汇总
1. 苹果体系自带的结构:
- 图形界面
UIKit
- 中心动画
CoreAnimation
- 首要在GPU上作业,用于动画作用和图层办理
- 2D图形制作和烘托
CoreGraphics(Quartz2D)
- 首要在CPU上作业,用于2D图形制作和烘托
- 图画处理和滤镜 CoreImage
- 首要在GPU上作业,用于图画处理和滤镜作用
- 图形烘托和核算 Metal
- 首要在GPU上作业,用于高功用图形烘托和核算
- 游戏引擎
- Scene Kit (3D)
- Sprite Kit (2D)
2.优秀的第三方库:
- 滤镜处理 GPUImage
- 首要在GPU上作业,供给了丰厚的图画处理和滤镜功用
- 核算机视觉 OpenCV
- 首要在CPU上作业,用于核算机视觉和图画处理
- 跨渠道图形结构 OpenGLES
- 首要在GPU上作业,用于完结3D图形烘托和游戏开发
毫无疑问,开发者们接触得最多的结构是以下几个,UIKit、Core Animation,Core Graphic, Core Image。下面简要介绍这几个结构,趁便介绍下GPUImage
:
二、UIKit结构
1. UIKit结构简介
UIKit是iOS运用程序开发的根底结构之一,也是iOS开发中的一个中心结构。它供给了一系列的类和组件,经过UIKit,开发者能够快速构建各种界面元素、完结用户交互和动画作用.
UIKit的首要功用和组件:
- 视图(View):用于构建运用程序的用户界面,包含
- 根本视图
- 容器视图
- 表视图
- 集合视图
- …
- 控件(Control):供给了各种用户交互控件,如:
- 按钮、标签、文本框、滑块等
- 视图操控器(ViewController):用于办理视图的显现和交互,包含:
- UIViewController、UINavigationController、UITabBarController等。
- 动画(Animation):供给了动画作用的支撑,如:
- 视图动画、过渡动画、关键帧动画等。
- 手势辨认(GestureRecognizer): 用于辨认和处理用户手势操作,如:
- 点击、滑动、捏合等。
- 绘图(Drawing):供给了制作图形和文本的功用,如:
- 制作形状、烘托文本、处理图形上下文等。
- 1.制作形状:
- 运用UIBezierPath类能够制作各种形状,如直线、曲线、矩形、圆角矩形、椭圆等。
- 经过设置途径的特点(如线宽、色彩、填充等)能够定制制作作用。
- 2.制作文本:
- 运用NSString和NSAttributedString类能够制作文本内容。
- 经过UILabel、UITextView等控件能够显现文本内容,也能够经过CoreText结构完结更杂乱的文本排版作用。
- 3.制作图画:
- 运用UIImage类能够加载和显现图画。
- 经过UIImageView控件能够显现图画,也能够经过CoreGraphics结构完结图画的制作和处理。
- 4.制作图形上下文:
- 运用UIGraphicsBeginImageContextWithOptions函数能够创立一个图形上下文。
- 在图形上下文中能够进行制作操作,如制作形状、文本、图画等。
- 运用UIGraphicsGetImageFromCurrentImageContext函数能够获取制作的图画。
- 5.制作动画:
- 运用UIView的动画办法(如animateWithDuration:animations:)能够完结简略的视图动画作用。
- 经过CoreAnimation结构能够完结更杂乱的动画作用,如关键帧动画、过渡动画等。
- 6.制作途径:
- 运用UIBezierPath类能够创立和操作途径方针,完结杂乱的途径制作和操作。
- 经过CAShapeLayer图层能够将途径增加到视图中进行显现。
- 1.制作形状:
- 制作形状、烘托文本、处理图形上下文等。
- 文本排版(TextLayout):支撑文本的排版和显现,包含文本款式、字体、段落款式等。
- 多使命处理(Multitasking): 支撑运用程序在多使命环境下的处理和适配。
- 1.多使命处理形式:
- 前台形式:运用程序在前台运行,呼运用户交互和显现界面。
- 后台形式:运用程序在后台运行,履行一些特定的使命,如音频播映、方位更新等。
- 多使命处理:运用程序能够一起履行多个使命,如下载数据、处理网络恳求等。
- 2.多使命处理功用:
- 后台履行使命:经过运用后台使命、后台会话等机制,运用程序能够在后台履行一些使命,如下载、上传数据等。
- 多线程处理:经过运用GCD(GrandCentralDispatch)和OperationQueue等多线程技能,运用程序能够在多个线程上履行并发使命,进步功用和呼应速度。
- 多使命处理状况办理:运用程序能够经过UIApplication类的状况改动告诉来办理多使命处理状况,如进入后台、恢复前台等。
- 3.多使命处理场景:
- 音频播映:运用程序能够在后台继续播映音频。
- 方位更新:运用程序能够在后台更新方位信息。
- 网络恳求:运用程序能够在后台履行网络恳求和数据下载。
- 数据处理:运用程序能够在后台处理数据、核算等使命。
- 1.多使命处理形式:
- 其它:
- 一些类: UIColor(色彩操作)、UIFont和UIScreen(供给字体和屏幕信息)
2. UIKit与Core Graphics的关系:
UIKit的绘图功用首要用于完结简略的图形制作、文本显现和图画处理,适用于构建根本的用户界面元素和视图作用。
关于更杂乱的绘图需求,能够结合CoreGraphics
结构来完结更丰厚用户界面和图形作用
以下是UIKit与CoreGraphics结合运用的一些常见场景和办法:
-
1.制作自界说视图:
- 能够经过承继UIView类,并重写drawRect办法,在其间运用CoreGraphics制作自界说的图形、文本或图画。
- 在drawRect办法中,能够创立UIBezierPath方针、设置制作特点(如色彩、线宽等),并调用CoreGraphics的制作办法来完结自界说制作作用。
-
2.制作图形和文本:
- 运用UIKit供给的控件和视图来构建用户界面,一起能够运用CoreGraphics来完结一些特别的制作作用,如突变布景、暗影作用等。
- 经过CoreGraphics的文本制作功用,能够完结更灵活的文本排版和款式设置。
-
3.图形上下文的办理:
- 能够经过UIGraphicsGetCurrentContext函数获取当时的图形上下文,然后运用CoreGraphics在该上下文中进行制作操作。
- 在制作进程中,能够运用UIGraphicsPushContext和UIGraphicsPopContext函数来办理图形上下文的压栈和出栈。
-
4.图形动画作用:
- 能够结合UIKit的动画办法和CoreGraphics的制作功用,完结一些杂乱的图形动画作用。
- 经过UIView的动画办法和CoreGraphics的制作办法结合运用,能够完结视图的滑润过渡和动态作用。
-
5.图形处理和滤镜作用:
- 能够运用CoreGraphics对图画进行处理,如裁剪、缩放、旋转等操作。
- 结合CoreImage结构,能够完结更杂乱的图画处理和滤镜作用,为用户界面增加更多的视觉作用。
3. 代码示例:
在UIKit中,UIView类本身在制作时主动创立一个图形环境,即Core Graphics
层的CGContext
类型,作为当时的图形制作环境。
在制作时能够调用 UIGraphicsGetCurrentContext
函数获得当时的图形环境;
3.1 制作自界说视图|制作途径:
Objective-C示例:
//这段代码便是在UIView的子类中调用 UIGraphicsGetCurrentContext 函数获得当时的图形环境,然后向该图形环境增加途径,最后制作。
- (void)drawRect:(CGRect)rect {
//1.获取上下文
CGContextRef contextRef = UIGraphicsGetCurrentContext();
//2.描绘途径
UIBezierPath * path = [UIBezierPath bezierPath];
//起点
[path moveToPoint:CGPointMake(10, 10)];
//结尾
[path addLineToPoint:CGPointMake(100, 100)];
//设置色彩
[[UIColor whiteColor]setStroke];
//3.增加途径
CGContextAddPath(contextRef, path.CGPath);
//显现途径
CGContextStrokePath(contextRef);
}
// Objective-C 代码示例:
// CustomView.h
#import <UIKit/UIKit.h>
@interface CustomView : UIView
@end
// CustomView.m
#import "CustomView.h"
@implementation CustomView
- (void)drawRect:(CGRect)rect {
//1.获取上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作途径
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, 50, 50);
CGContextAddLineToPoint(context, 200, 200);
CGContextStrokePath(context);
}
@end
Swift示例:
// Swift 代码示例
// CustomView.swift
import UIKit
class CustomView: UIView {
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
let path = UIBezierPath()
path.move(to: CGPoint(x: 50, y: 50))
path.addLine(to: CGPoint(x: 150, y: 150))
path.addArc(withCenter: CGPoint(x: 100, y: 100), radius: 50, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
context.setStrokeColor(UIColor.red.cgColor)
context.setLineWidth(2.0)
context.addPath(path.cgPath)
context.strokePath()
}
}
}
3.2 制作自界说视图|制作形状、文本等:
Objective-C示例:
// CustomView.h
#import <UIKit/UIKit.h>
@interface CustomView : UIView
@end
// CustomView.m
#import "CustomView.h"
@implementation CustomView
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作矩形
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(50, 50, 100, 100));
// 制作圆形
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillEllipseInRect(context, CGRectMake(150, 150, 50, 50));
// 制作文本
NSString *text = @"Hello, Core Graphics!";
[text drawAtPoint:CGPointMake(50, 200) withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:16], NSForegroundColorAttributeName: [UIColor greenColor]}];
}
@end
Swift示例:
// CustomView.swift
import UIKit
class CustomView: UIView {
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作矩形
context.setFillColor(UIColor.blue.cgColor)
context.fill(CGRect(x: 50, y: 50, width: 100, height: 100))
// 制作圆形
context.setFillColor(UIColor.red.cgColor)
context.fillEllipse(in: CGRect(x: 150, y: 150, width: 50, height: 50))
// 制作文本
let text = "Hello, Core Graphics!"
let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.green]
text.draw(at: CGPoint(x: 50, y: 200), withAttributes: attributes)
}
}
}
3.3 创立自界说按钮:
Objective-C示例:
// Objective-C示例:
// CustomButton.h
#import <UIKit/UIKit.h>
@interface CustomButton : UIButton
@end
// CustomButton.m
#import "CustomButton.h"
@implementation CustomButton
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作布景
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, rect);
// 制作边框
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextStrokeRect(context, rect);
// 制作文本
NSString *text = @"Custom Button";
NSDictionary *attributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:16.0], NSForegroundColorAttributeName: [UIColor whiteColor] };
CGSize textSize = [text sizeWithAttributes:attributes];
CGPoint textOrigin = CGPointMake((CGRectGetWidth(rect) - textSize.width) / 2, (CGRectGetHeight(rect) - textSize.height) / 2);
[text drawAtPoint:textOrigin withAttributes:attributes];
}
@end
Swift示例:
// Swift示例:
// CustomButton.swift
import UIKit
class CustomButton: UIButton {
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作布景
context.setFillColor(UIColor.blue.cgColor)
context.fill(rect)
// 制作边框
context.setStrokeColor(UIColor.white.cgColor)
context.stroke(rect)
// 制作文本
let text = "Custom Button"
let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16.0), NSAttributedString.Key.foregroundColor: UIColor.white]
let textSize = text.size(withAttributes: attributes)
let textOrigin = CGPoint(x: (rect.width - textSize.width) / 2, y: (rect.height - textSize.height) / 2)
text.draw(at: textOrigin, withAttributes: attributes)
}
}
}
3.4 制作图画和文本:
Objective-C示例:
// Objective-C示例:
// 在UIView的drawRect办法中结合Core Graphics制作图画和文本
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作图画
UIImage *image = [UIImage imageNamed:@"exampleImage"];
CGContextDrawImage(context, CGRectMake(20, 20, 100, 100), image.CGImage);
// 增加滤镜作用
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextSetAlpha(context, 0.5);
// 制作文本
NSString *text = @"Hello, World!";
[text drawAtPoint:CGPointMake(20, 150) withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:16], NSForegroundColorAttributeName: [UIColor redColor]}];
}
Swift示例:
// Swift示例:
// 在UIView的draw办法中结合Core Graphics制作图画和文本
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作图画
if let image = UIImage(named: "exampleImage") {
context.draw(image.cgImage!, in: CGRect(x: 20, y: 20, width: 100, height: 100))
}
// 增加滤镜作用
context.setBlendMode(.multiply)
context.setAlpha(0.5)
// 制作文本
let text = "Hello, World!"
let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.red]
text.draw(at: CGPoint(x: 20, y: 150), withAttributes: attributes)
}
}
3.5 制作动画作用:
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
@interface CustomView : UIView
@end
@implementation CustomView
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作途径
CGContextSetStrokeColorWithColor(context, [UIColor.redColor CGColor]);
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, 50, 50);
CGContextAddLineToPoint(context, 200, 200);
CGContextStrokePath(context);
// 创立途径动画
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
pathAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
pathAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
pathAnimation.duration = 2.0;
// 增加动画
[self.layer addAnimation:pathAnimation forKey:@"position"];
}
@end
Swift示例:
// Swift示例:
import UIKit
class CustomView: UIView {
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作途径
context.setStrokeColor(UIColor.red.cgColor)
context.setLineWidth(2.0)
context.move(to: CGPoint(x: 50, y: 50))
context.addLine(to: CGPoint(x: 200, y: 200))
context.strokePath()
// 创立途径动画
let pathAnimation = CABasicAnimation(keyPath: "position")
pathAnimation.fromValue = CGPoint(x: 50, y: 50)
pathAnimation.toValue = CGPoint(x: 200, y: 200)
pathAnimation.duration = 2.0
// 增加动画
layer.add(pathAnimation, forKey: "position")
}
}
}
3.6 制作图形上下文:
Objective-C示例:
// Objective-C示例:
- (UIImage *)drawCustomImage {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作矩形
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(50, 50, 100, 100));
// 制作文本
NSString *text = @"Hello, Core Graphics!";
[text drawAtPoint:CGPointMake(20, 20) withAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:16], NSForegroundColorAttributeName: [UIColor redColor]}];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Swift示例:
// Swift示例:
func drawCustomImage() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 200), false, 0.0)
if let context = UIGraphicsGetCurrentContext() {
// 制作矩形
context.setFillColor(UIColor.blue.cgColor)
context.fill(CGRect(x: 50, y: 50, width: 100, height: 100))
// 制作文本
let text = "Hello, Core Graphics!"
let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16), NSAttributedString.Key.foregroundColor: UIColor.red]
text.draw(at: CGPoint(x: 20, y: 20), withAttributes: attributes)
if let image = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
return image
}
}
return nil
}
三、 Core Animation 结构
1. 首要特点和功用
CoreAnimation结构是iOS和macOS渠道上用于完结动画效
果和图层办理
的中心结构。
它供给了一套强壮的API,用于创立、组合和办理图层,完结各种动画作用和视觉作用。以下是CoreAnimation结构的一些首要特点和功用:
-
- 图层(CALayer)与图层办理:
- CALayer是Core Animation结构的中心,用于办理视图的显现和动画作用。
- CALayer供给了丰厚的特点和办法,用于操控视图的外观、方位、大小等。
- CALayer担任视图的烘托、布局、动画等操作,是视图的可视化表明。
-
- 动画(CAAnimation):
- CAAnimation是Core Animation结构中用于完结动画作用的基类。
- 能够经过设置动画的特点和持续时刻来完结各种动画作用。
- CAAnimation包含:
- 根底动画(CABasicAnimation)
- 关键帧动画(CAKeyframeAnimation)
- 过渡动画(CATransition)等类型。
-
- 图层组合:
- 能够经过图层组合和图层树的办法来办理和组织视图的层级关系。
- 能够创立杂乱的图层结构,完结多层次的视图组合和作用叠加。
-
- 隐式动画:
- Core Animation结构支撑隐式动画,即经过改动图层的特点值来主动触发动画作用。
- 能够经过设置图层的特点值来完结简略的动画作用,无需显式创立动画方针。
-
- 图层烘托:
- Core Animation结构运用GPU硬件加快来完结图层的烘托和动画作用。
- 能够完结流通的动画作用和高功用的图层烘托。
-
- 交互作用:
- Core Animation结构支撑用户交互作用,如手势辨认、点击事情等。
- 能够经过手势辨认和事情处理来完结交互式的动画作用。
2. 中心类介绍
Core Animation结构中的中心类首要包含以下几个:
-
- CALayer:
- CALayer是Core Animation结构中的中心类,用于办理视图的显现和动画作用。
- CALayer担任视图的烘托、布局、动画等操作,是视图的可视化表明。
- CALayer供给了丰厚的特点和办法,用于操控视图的外观、方位、大小等。
-
- CAAnimation:
- CAAnimation是Core Animation结构中用于完结动画作用的基类。
- CAAnimation包含根底动画(CABasicAnimation)、关键帧动画(CAKeyframeAnimation)、过渡动画(CATransition)等类型。
- 开发者能够经过CAAnimation来创立各种动画作用,如平移、旋转、缩放等。
-
- CATransform3D:
- CATransform3D是Core Animation结构中用于完结3D改换的类。
- CATransform3D能够完结视图的平移、旋转、缩放等3D改换作用。
- 开发者能够经过CATransform3D来创立杂乱的3D改换作用,完结炫酷的视觉作用。
-
- CAEmitterLayer:
- CAEmitterLayer是Core Animation结构中用于完结粒子作用的类。
- CAEmitterLayer能够创立和办理粒子体系,完结雪花、火焰、烟雾等作用。
- 开发者能够经过CAEmitterLayer来完结丰厚的粒子作用,为运用程序增加动感和生动性。
-
- CAShapeLayer:
- CAShapeLayer是Core Animation结构中用于制作形状的类。
- CAShapeLayer能够创立和办理各种形状,如矩形、圆角矩形、椭圆等。
- 开发者能够经过CAShapeLayer来完结杂乱的形状制作和途径动画作用。
3. 代码示例
3.1 动画
Objective-C示例:
// Objective-C示例:
// 创立根底动画(CABasicAnimation)
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
basicAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
basicAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
basicAnimation.duration = 1.0;
// 创立关键帧动画(CAKeyframeAnimation)
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
keyframeAnimation.values = @[@0, @(M_PI_2), @0];
keyframeAnimation.duration = 1.0;
// 创立过渡动画(CATransition)
CATransition *transition = [CATransition animation];
transition.type = kCATransitionFade;
transition.duration = 1.0;
// 动画的组合
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[basicAnimation, keyframeAnimation, transition];
animationGroup.duration = 2.0;
// 将动画增加到视图的图层上
CALayer *layer = [CALayer layer];
[layer addAnimation:animationGroup forKey:@"animationGroup"];
Swift示例:
// Swift示例:
// 创立根底动画(CABasicAnimation)
let basicAnimation = CABasicAnimation(keyPath: "position")
basicAnimation.fromValue = CGPoint(x: 100, y: 100)
basicAnimation.toValue = CGPoint(x: 200, y: 200)
basicAnimation.duration = 1.0
// 创立关键帧动画(CAKeyframeAnimation)
let keyframeAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
keyframeAnimation.values = [0, .pi/2, 0]
keyframeAnimation.duration = 1.0
// 创立过渡动画(CATransition)
let transition = CATransition()
transition.type = .fade
transition.duration = 1.0
// 动画的组合
let animationGroup = CAAnimationGroup()
animationGroup.animations = [basicAnimation, keyframeAnimation, transition]
animationGroup.duration = 2.0
// 将动画增加到视图的图层上
let layer = CALayer()
layer.add(animationGroup, forKey: "animationGroup")
3.2 图层组合
Objective-C示例:
// Objective-C示例:
CALayer *parentLayer = [CALayer layer];
parentLayer.frame = CGRectMake(50, 50, 200, 200);
parentLayer.backgroundColor = [UIColor blueColor].CGColor;
CALayer *childLayer1 = [CALayer layer];
childLayer1.frame = CGRectMake(20, 20, 100, 100);
childLayer1.backgroundColor = [UIColor redColor].CGColor;
CALayer *childLayer2 = [CALayer layer];
childLayer2.frame = CGRectMake(50, 50, 100, 100);
childLayer2.backgroundColor = [UIColor greenColor].CGColor;
[parentLayer addSublayer:childLayer1];
[parentLayer addSublayer:childLayer2];
[self.view.layer addSublayer:parentLayer];
Swift示例:
// Swift示例:
let parentLayer = CALayer()
parentLayer.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
parentLayer.backgroundColor = UIColor.blue.cgColor
let childLayer1 = CALayer()
childLayer1.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
childLayer1.backgroundColor = UIColor.red.cgColor
let childLayer2 = CALayer()
childLayer2.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
childLayer2.backgroundColor = UIColor.green.cgColor
parentLayer.addSublayer(childLayer1)
parentLayer.addSublayer(childLayer2)
view.layer.addSublayer(parentLayer)
3.3 隐式动画
Objective-C示例:
// Objective-C示例:
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.backgroundColor = [UIColor blueColor].CGColor;
// 隐式动画:改动图层的方位特点
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
layer.position = CGPointMake(150, 150);
[CATransaction commit];
Swift示例:
// Swift示例:
let layer = CALayer()
layer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
layer.backgroundColor = UIColor.blue.cgColor
// 隐式动画:改动图层的方位特点
CATransaction.begin()
CATransaction.setAnimationDuration(1.0)
layer.position = CGPoint(x: 150, y: 150)
CATransaction.commit()
3.4 图层烘托
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ViewController : UIViewController
@property (nonatomic, strong) CALayer *customLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创立自界说图层
self.customLayer = [CALayer layer];
self.customLayer.frame = CGRectMake(50, 50, 100, 100);
self.customLayer.backgroundColor = [UIColor blueColor].CGColor;
// 增加图层到视图
[self.view.layer addSublayer:self.customLayer];
// 创立根底动画
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.fromValue = [NSValue valueWithCGPoint:self.customLayer.position];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
animation.duration = 1.0;
// 增加动画到图层
[self.customLayer addAnimation:animation forKey:@"position"];
}
@end
Swift示例:
// Swift示例:
import UIKit
class ViewController: UIViewController {
var customLayer: CALayer!
override func viewDidLoad() {
super.viewDidLoad()
// 创立自界说图层
customLayer = CALayer()
customLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
customLayer.backgroundColor = UIColor.blue.cgColor
// 增加图层到视图
view.layer.addSublayer(customLayer)
// 创立根底动画
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = customLayer.position
animation.toValue = CGPoint(x: 200, y: 200)
animation.duration = 1.0
// 增加动画到图层
customLayer.add(animation, forKey: "position")
}
}
3.5 交互作用
Objective-C示例:
// Objective-C示例:
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()
@property (nonatomic, strong) CALayer *animationLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.animationLayer = [CALayer layer];
self.animationLayer.backgroundColor = [UIColor blueColor].CGColor;
self.animationLayer.frame = CGRectMake(50, 50, 100, 100);
[self.view.layer addSublayer:self.animationLayer];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGestureRecognizer:tapGesture];
}
- (void)handleTap:(UITapGestureRecognizer *)gesture {
CGPoint location = [gesture locationInView:self.view];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:location];
animation.duration = 0.5;
[self.animationLayer addAnimation:animation forKey:@"position"];
}
@end
Swift示例:
// Swift示例:
import UIKit
class ViewController: UIViewController {
var animationLayer: CALayer!
override func viewDidLoad() {
super.viewDidLoad()
animationLayer = CALayer()
animationLayer.backgroundColor = UIColor.blue.cgColor
animationLayer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
view.layer.addSublayer(animationLayer)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
view.addGestureRecognizer(tapGesture)
}
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
let location = gesture.location(in: view)
let animation = CABasicAnimation(keyPath: "position")
animation.toValue = location
animation.duration = 0.5
animationLayer.add(animation, forKey: "position")
}
}
-
Core Animation
是常用的结构之一。它比 UIKit 和 AppKit 更底层。正如咱们所知,UIView底下封装了一层CALayer树,Core Animation 层是真正的烘托层,咱们之所以能在屏幕上看到内容,真正的烘托作业是在 Core Animation 层进行的。 - Core Animation 是一套Objective-C API,完结了一个高功用的复合引擎,并供给一个简略易用的编程接口,给用户UI增加滑润运动和动态反馈才能。
- Core Animation 是 UIKit 完结动画和改换的根底,也担任视图的复合功用。运用Core Animation能够完结定制动画和细粒度的动画操控,创立杂乱的、支撑动画和改换的layered 2D视图
- OpenGL ES的内容也能够与Core Animation内容进行集成。
- 为了运用Core Animation完结动画,能够修改 层的特点值 来触发一个action方针的履行,不同的action方针完结不同的动画。Core Animation 供给了一组基类及子类,供给对不同动画类型的支撑:
- CAAnimation 是一个笼统公共基类,CAAnimation选用CAMediaTiming 和CAAction协议为动画供给时刻(如周期、速度、重复次数等)和action行为(启动、停止等)。
- CAPropertyAnimation 是 CAAnimation的笼统子类,为动画供给一个由一个key途径规定的层特点的支撑;
- CABasicAnimation 是CAPropertyAnimation的详细子类,为一个层特点供给简略插入才能。
- CAKeyframeAnimation 也是CAPropertyAnimation的详细子类,供给key帧动画支撑。
四、 Core Graphics & Quartz 2D
1. 首要特点和功用
Core Graphics(Quartz 2D)是iOS和macOS渠道上的2D绘图引擎,它是一套C-based API,用于完结图形制作
、图画处理
和文本烘托
等功用。
以下是Core Graphics & Quartz 2D的详细介绍:
-
- 绘图功用:
- 绘图上下文:
- Core Graphics运用绘图上下文(Graphics Context)来进行制作操作,能够是根据位图的上下文、PDF上下文等。
- Core Graphics供给了丰厚的绘图功用,包含:
- 制作形状(直线、矩形、椭圆等)
- 制作途径(自界说途径、曲线途径等)
- 制作图画(位图图画、矢量图画等)
- …
- 开发者能够在不同类型的上下文中进行制作操作,创立自界说的绘图作用,完结各种绘图需求
-
- 图画处理:
- Core Graphics支撑图画的
加载
、制作
、裁剪
、改换
、组成
、烘托
等操作 完结图画的特效和优化
-
- 文本烘托:
- Core Graphics供给了文本烘托功用,能够烘托
文本内容
,能够操控文本款式
、排版布局
等完结文本的自界说烘托。
-
- 图形上下文:
- Core Graphics运用图形上下文(Graphics Context)来办理绘图环境的状况和特点。
- 经过设置图形上下文的特点来操控绘图作用,如色彩、线宽、填充形式等。
-
- 色彩和烘托:
- Core Graphics支撑色彩办理和烘托操作,能够设置
填充色彩
、描边色彩
、突变色
等。
-
- 图形改换:
- Core Graphics供给了图形改换的功用,能够完结
平移
、旋转
、缩放
等改换操作。
-
- 坐标系:
- Core Graphics运用笛卡尔坐标系,原点在左下角,x轴向右延伸,y轴向上延伸。
- 开发者能够经过坐标改换来完结坐标系的转化和调整,完结杂乱的绘图作用和布局。
-
- 功用优化:
- Core Graphics运用GPU硬件加快来完结图形烘托和处理,进步绘图功率和功用。
- 开发者能够经过合理运用Core Graphics的API和功用来优化绘图功用,完结流通的图形制作和处理
-
- 其它
-
Core Graphics
(运用Quartz 2D引擎)- 当开发者需求在运行时创立图画时,能够运用 Core Graphics 去制作,
运行时实时核算
、制作一系列图画帧
来完结动画。 - 与之相对的是运行前创立图画(例如从磁盘中或内存中现已创立好的UIImage图画)
- 当开发者需求在运行时创立图画时,能够运用 Core Graphics 去制作,
-
Quartz 2D
- Quartz 2D是Core Graphics中的2D 制作出现引擎。
- Quartz 2D能够与一切的图形和动画技能(如
Core Animation
,OpenGL ES
, 和UIKit
等)一起运用。Quartz 2D选用paint形式进行制作。
2. 中心类介绍
Core Graphics(Quartz 2D)结构中的中心类首要包含以下几个:
-
- CGContext:
- CGContext是Core Graphics中的
绘图上下文
,用于履行绘图操作和烘托图形。 - CGContext供给了制作途径、图画、文本等的功用,是完结图形制作的中心类。
-
- CGPath:
- CGPath是Core Graphics中
表明途径
的类,用于创立和办理途径方针。 - CGPath能够包含
直线
、曲线
、矩形
、椭圆
等形状,用于界说制作的轮廓和形状。 - CGPath能够被填充和stroke
-
- CGImage:
- CGImage是Core Graphics中
表明图画
的类,用于加载、创立和处理位图图画。 - CGImage能够从文件、数据或其他来历创立,用于图画的制作和处理。
-
- CGColor:
- CGColor是Core Graphics中
表明色彩
的类,用于界说制作和填充的色彩。 - CGColor能够表明RGB、RGBA、灰度等色彩空间,用于设置制作和填充的色彩值。
-
CGColor
和CGColorSpace
;用来进行色彩和色彩空间办理;
-
- CGGradient:
- CGGradient是Core Graphics中
表明突变
的类,用于创立和办理色彩突变作用。 - CGGradient能够
界说线性突变
、径向突变
等作用,用于完结丰厚的色彩突变作用。 -
CGShading
和CGGradient
:用于制作剃度;
-
- CTFont:
- CTFont是Core Text结构中
表明字体
的类,用于处理文本的字体和排版。 - CTFont能够设置字体的
款式
、大小
、粗细
等特点,用于文本的烘托和显现。
- 其他常用类:
-
CGLayer
:用来表明一个能够用于重复制作和offscreen制作的制作层; -
CGPattern
:用来表明Pattern,用于重复制作; -
CGPDFContentStream
、CGPDFScanner
、CGPDFPage
、CGPDFObject
,CGPDFStream
,CGPDFString
等用来进行pdf文件的创立、解析和显现
-
3. 代码示例
3.1 绘图功用|制作形状(直线、曲线、矩形、椭圆等)
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作直线
CGContextMoveToPoint(context, 50, 50);
CGContextAddLineToPoint(context, 150, 150);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextStrokePath(context);
// 制作曲线
CGContextMoveToPoint(context, 50, 100);
CGContextAddQuadCurveToPoint(context, 100, 50, 150, 100);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextStrokePath(context);
// 制作矩形
CGContextAddRect(context, CGRectMake(50, 150, 100, 50));
CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
CGContextFillPath(context);
// 制作椭圆
CGContextAddEllipseInRect(context, CGRectMake(50, 200, 100, 50));
CGContextSetStrokeColorWithColor(context, [UIColor purpleColor].CGColor);
CGContextStrokePath(context);
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作直线
context.move(to: CGPoint(x: 50, y: 50))
context.addLine(to: CGPoint(x: 150, y: 150))
context.setStrokeColor(UIColor.red.cgColor)
context.strokePath()
// 制作曲线
context.move(to: CGPoint(x: 50, y: 100))
context.addQuadCurve(to: CGPoint(x: 150, y: 100), control: CGPoint(x: 100, y: 50))
context.setStrokeColor(UIColor.blue.cgColor)
context.strokePath()
// 制作矩形
context.addRect(CGRect(x: 50, y: 150, width: 100, height: 50))
context.setFillColor(UIColor.green.cgColor)
context.fillPath()
// 制作椭圆
context.addEllipse(in: CGRect(x: 50, y: 200, width: 100, height: 50))
context.setStrokeColor(UIColor.purple.cgColor)
context.strokePath()
}
}
3.2 绘图功用|制作途径(自界说途径、曲线途径等)
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作自界说途径
CGContextMoveToPoint(context, 50, 50);
CGContextAddLineToPoint(context, 150, 50);
CGContextAddLineToPoint(context, 100, 100);
CGContextClosePath(context);
// 制作曲线途径
CGContextMoveToPoint(context, 50, 150);
CGContextAddQuadCurveToPoint(context, 100, 200, 150, 150);
// 设置途径款式
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
// 制作途径
CGContextDrawPath(context, kCGPathFillStroke);
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 制作自界说途径
context.move(to: CGPoint(x: 50, y: 50))
context.addLine(to: CGPoint(x: 150, y: 50))
context.addLine(to: CGPoint(x: 100, y: 100))
context.closePath()
// 制作曲线途径
context.move(to: CGPoint(x: 50, y: 150))
context.addQuadCurve(to: CGPoint(x: 150, y: 150), control: CGPoint(x: 100, y: 200))
// 设置途径款式
context.setLineWidth(2.0)
context.setStrokeColor(UIColor.blue.cgColor)
// 制作途径
context.drawPath(using: .fillStroke)
}
}
3.3 绘图功用|制作图画(位图图画、矢量图画等)
Objective-C示例:
// Objective-C示例:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创立绘图上下文
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作矩形
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(50, 50, 100, 100));
// 制作图画
UIImage *image = [UIImage imageNamed:@"exampleImage"];
[image drawInRect:CGRectMake(20, 20, 50, 50)];
// 获取制作的图画
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// 显现制作的图画
UIImageView *imageView = [[UIImageView alloc] initWithImage:resultImage];
[self.view addSubview:imageView];
}
@end
Swift示例:
// Swift示例:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// 创立绘图上下文
UIGraphicsBeginImageContextWithOptions(CGSize(width: 200, height: 200), false, 0.0)
if let context = UIGraphicsGetCurrentContext() {
// 制作矩形
context.setFillColor(UIColor.blue.cgColor)
context.fill(CGRect(x: 50, y: 50, width: 100, height: 100))
// 制作图画
if let image = UIImage(named: "exampleImage") {
image.draw(in: CGRect(x: 20, y: 20, width: 50, height: 50))
}
// 获取制作的图画
if let resultImage = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
// 显现制作的图画
let imageView = UIImageView(image: resultImage)
imageView.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
view.addSubview(imageView)
}
}
}
}
3.4 图画处理|加载
、制作
、裁剪
、改换
、组成
、烘托
Objective-C示例:
// Objective-C示例:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *originalImage = [UIImage imageNamed:@"original_image"];
// 创立绘图上下文
UIGraphicsBeginImageContextWithOptions(originalImage.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
// 制作原始图画
[originalImage drawInRect:CGRectMake(0, 0, originalImage.size.width, originalImage.size.height)];
// 裁剪图画
CGContextClipToRect(context, CGRectMake(0, 0, originalImage.size.width / 2, originalImage.size.height));
// 创立改换矩阵
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);
CGContextConcatCTM(context, transform);
// 制作改换后的图画
UIImage *transformedImage = UIGraphicsGetImageFromCurrentImageContext();
// 组成图画
UIImage *compositeImage = [UIImage imageNamed:@"overlay_image"];
[compositeImage drawInRect:CGRectMake(0, 0, originalImage.size.width, originalImage.size.height) blendMode:kCGBlendModeNormal alpha:0.5];
// 烘托图画
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, originalImage.size.width, originalImage.size.height)];
self.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
[self.view addSubview:self.imageView];
UIGraphicsEndImageContext();
}
@end
Swift示例:
// Swift示例:
import UIKit
class ViewController: UIViewController {
var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
if let originalImage = UIImage(named: "original_image") {
// 创立绘图上下文
UIGraphicsBeginImageContextWithOptions(originalImage.size, false, 0.0)
if let context = UIGraphicsGetCurrentContext() {
// 制作原始图画
originalImage.draw(in: CGRect(x: 0, y: 0, width: originalImage.size.width, height: originalImage.size.height))
// 裁剪图画
context.clip(to: CGRect(x: 0, y: 0, width: originalImage.size.width / 2, height: originalImage.size.height))
// 创立改换矩阵
let transform = CGAffineTransform(rotationAngle: CGFloat.pi / 4)
context.concatenate(transform)
// 制作改换后的图画
let transformedImage = UIGraphicsGetImageFromCurrentImageContext()
// 组成图画
if let compositeImage = UIImage(named: "overlay_image") {
compositeImage.draw(in: CGRect(x: 0, y: 0, width: originalImage.size.width, height: originalImage.size.height), blendMode: .normal, alpha: 0.5)
}
// 烘托图画
imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: originalImage.size.width, height: originalImage.size.height))
imageView.image = UIGraphicsGetImageFromCurrentImageContext()
view.addSubview(imageView)
UIGraphicsEndImageContext()
}
}
}
}
3.5 文本烘托|烘托文本内容,操控文本款式、排版布局
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
- (void)drawTextWithCustomStyle {
CGContextRef context = UIGraphicsGetCurrentContext();
NSString *text = @"Hello, Core Graphics!";
UIFont *font = [UIFont systemFontOfSize:16];
UIColor *textColor = [UIColor redColor];
NSDictionary *attributes = @{NSFontAttributeName: font, NSForegroundColorAttributeName: textColor};
CGSize textSize = [text sizeWithAttributes:attributes];
CGRect textRect = CGRectMake(50, 50, textSize.width, textSize.height);
[text drawInRect:textRect withAttributes:attributes];
}
Swift示例:
// Swift示例:
import UIKit
func drawTextWithCustomStyle() {
if let context = UIGraphicsGetCurrentContext() {
let text = "Hello, Core Graphics!"
let font = UIFont.systemFont(ofSize: 16)
let textColor = UIColor.red
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attributes: [NSAttributedString.Key: Any] = [
.font: font,
.foregroundColor: textColor,
.paragraphStyle: paragraphStyle
]
let textSize = text.size(withAttributes: attributes)
let textRect = CGRect(x: 50, y: 50, width: textSize.width, height: textSize.height)
text.draw(in: textRect, withAttributes: attributes)
}
}
3.6 图形上下文|绘图 色彩、线宽、填充形式
Objective-C示例:
// Objective-C示例:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 设置绘图色彩
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
// 设置线宽
CGContextSetLineWidth(context, 2.0);
// 制作矩形
CGContextAddRect(context, CGRectMake(50, 50, 100, 100));
// 填充矩形
CGContextFillPath(context);
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 设置绘图色彩
context.setFillColor(UIColor.blue.cgColor)
context.setStrokeColor(UIColor.red.cgColor)
// 设置线宽
context.setLineWidth(2.0)
// 制作矩形
context.addRect(CGRect(x: 50, y: 50, width: 100, height: 100))
// 填充矩形
context.fillPath()
}
}
3.7 色彩和烘托|填充色彩
、描边色彩
、突变色
Objective-C示例:
// Objective-C示例:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 填充色彩
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, rect);
// 描边色彩
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextStrokeRect(context, CGRectMake(50, 50, 100, 100));
// 创立突变色
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0.0, 1.0};
NSArray *colors = @[(id)[UIColor redColor].CGColor, (id)[UIColor blueColor].CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
// 制作突变色
CGContextDrawLinearGradient(context, gradient, CGPointMake(0, 0), CGPointMake(0, CGRectGetHeight(rect)), kCGGradientDrawsBeforeStartLocation);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 填充色彩
context.setFillColor(UIColor.blue.cgColor)
context.fill(rect)
// 描边色彩
context.setStrokeColor(UIColor.red.cgColor)
context.stroke(CGRect(x: 50, y: 50, width: 100, height: 100))
// 创立突变色
let colorSpace = CGColorSpaceCreateDeviceRGB()
let locations: [CGFloat] = [0.0, 1.0]
if let gradient = CGGradient(colorsSpace: colorSpace, colors: [UIColor.red.cgColor, UIColor.blue.cgColor] as CFArray, locations: locations) {
// 制作突变色
context.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: rect.height), options: [])
}
}
}
3.8 图形改换|平移、旋转、缩放
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 平移
CGContextTranslateCTM(context, 50, 50);
// 旋转
CGContextRotateCTM(context, M_PI_4); // 45度
// 缩放
CGContextScaleCTM(context, 1.5, 1.5);
// 制作一个矩形
CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 0, 100, 100));
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 平移
context.translateBy(x: 50, y: 50)
// 旋转
context.rotate(by: CGFloat.pi / 4) // 45度
// 缩放
context.scaleBy(x: 1.5, y: 1.5)
// 制作一个矩形
context.setFillColor(UIColor.blue.cgColor)
context.fill(CGRect(x: 0, y: 0, width: 100, height: 100))
}
}
3.9 功用优化
Objective-C示例:
// Objective-C示例:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// 设置制作特点,如色彩、线宽等
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0);
// 功用优化:制止图形上下文的主动滑润处理
CGContextSetAllowsAntialiasing(context, NO);
// 功用优化:设置图形上下文的特点
CGContextSetShouldAntialias(context, YES); // 敞开抗锯齿
CGContextSetAllowsAntialiasing(context, YES); // 允许抗锯齿
CGContextSetInterpolationQuality(context, kCGInterpolationHigh); // 设置插值质量为高
// 制作大量图形
for (int i = 0; i < 1000; i++) {
CGContextMoveToPoint(context, i, 0);
CGContextAddLineToPoint(context, i, 100);
}
// 履行制作
CGContextStrokePath(context);
}
Swift示例:
// Swift示例:
override func draw(_ rect: CGRect) {
if let context = UIGraphicsGetCurrentContext() {
// 设置制作特点,如色彩、线宽等
context.setStrokeColor(UIColor.red.cgColor)
context.setLineWidth(2.0)
// 功用优化:制止图形上下文的主动滑润处理
context.setAllowsAntialiasing(false)
// 功用优化:设置图形上下文的特点
context.setShouldAntialias(true) // 敞开抗锯齿
context.setAllowsAntialiasing(true) // 允许抗锯齿
context.setInterpolationQuality(.high) // 设置插值质量为高
// 制作大量图形
for i in 0..<1000 {
context.move(to: CGPoint(x: i, y: 0))
context.addLine(to: CGPoint(x: i, y: 100))
}
// 履行制作
context.strokePath()
}
}
五、Core Image
Core Image是苹果供给的图画处理结构,首要用于完结图画处理
、滤镜运用
和图画剖析
等功用。以下是Core Image的中心关键:
1. 首要特点和功用
-
- 滤镜(Filter):
- Core Image供给了丰厚的滤镜作用,如
含糊
、锐化
、色彩调整
、边际检测
等。 - 开发者能够经过Core Image的滤镜功用对图画进行处理和增强。
- iOS 8 之后 引入 CIFilter,Core Image从此支撑自界说滤镜的创立和运用,完结个性化的图画处理作用。
-
- 图画处理链(Image Processing Pipeline):
- Core Image运用图画处理链来处理图画,包含
输入图画
、滤镜作用
、和输出图画
。 - 开发者能够构建自界说的图画处理链,完结杂乱的图画处理流程。
-
- 图画剖析(Image Analysis):
- Core Image支撑图画剖析功用,如
人脸检测
、特征辨认
、色彩辨认
、物体辨认
等。 - 开发者能够运用Core Image进行图画剖析,
提取图画中的信息和特征
。
-
- Metal功用优化:
- Core Image能够与Metal结构结合,运用GPU硬件加快来进步图画处理的功用。
- 开发者能够经过Metal结构优化Core Image的功用,完结高效的图画处理和滤镜作用。
-
- 图画格局转化(Image Format Conversion):
- Core Image支撑图画格局的转化和处理,如
色彩空间转化
、像素格局转化
等。 - 开发者能够运用Core Image进行图画格局的转化和处理,满足不同的图画处理需求。
-
- 实时预览(Real-time Preview):
- Core Image供给实时预览功用,能够在运用程序中实时显现滤镜作用的预览。
- 开发者能够经过Core Image完结实时的滤镜预览,便运用户调整和检查作用。
-
- 其它
-
Core Image
与 Core Graphics 恰恰相反- Core Graphics 用于在运行时创立图画
- 而 Core Image 是用来处理现已创立的图画的。
-
Core Image
是 iOS5 新加入到 iOS 渠道的一个图画处理结构,供给了强壮高效的图画处理功用, 用来对根据像素的图画进行操作与剖析, 内置了许多强壮的滤镜(Filter) (现在数量超过了180种), 这些Filter 供给了各式各样的作用, 而且还能够经过 滤镜链 将各种作用的 Filter叠加 起来形成强壮的自界说作用。- iOS8 之后更是支撑自界说 CIFilter,能够定制满足业务需求的杂乱作用。
-
Core Image
的优点在于非常高效。大部分情况下,它会在 GPU 中完结作业,但假如 GPU 忙,会运用 CPU 进行处理。假如设备支撑 Metal,那么会运用 Metal 处理。这些操作会在底层完结,Apple 的工程师们现已帮助开发者们完结这些操作了。- 例如他能够根据需求挑选 CPU 或许 GPU 来处理。
// 创立根据 CPU 的 CIContext 方针 (默许是根据 GPU,CPU 需求额定设置参数) context = [CIContext contextWithOptions: [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]]; // 创立根据 GPU 的 CIContext 方针 context = [CIContext contextWithOptions: nil]; // 创立根据 GPU 的 CIContext 方针 EAGLContext *eaglctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; context = [CIContext contextWithEAGLContext:eaglctx]; ```
2. 中心类介绍
-
- CIImage:
- CIImage是Core Image结构中表明图画数据的类,能够用来表明图画数据源
- CIImage能够从各种来历创立,如UIImage、CGImage、NSData、图画文件或许像素数据等,用于输入到Core Image的滤镜中进行处理。
-
- CIFilter:
- CIFilter是Core Image结构中的滤镜类,用于完结各种图画处理和滤镜作用。
- CIFilter包含了各种内置的滤镜作用,也能够自界说滤镜来完结特定的图画处理需求。
- 这个结构中对图片特点进行细节处理的类。它对一切的像素进行操作,用一些键-值设置来决定详细操作的程度。
-
- CIContext:
- CIContext是Core Image结构中的上下文类,用于办理图画处理的环境和输出。
- CIContext能够指定烘托方针(如屏幕、图画文件)、烘托选项(如色彩空间、缩放份额)等参数。
-
- CIFeature:
- CIFeature是Core Image结构中的特征类,用于检测图画中的特征和方针。
- CIFeature能够用于人脸检测、文本辨认、条形码辨认等运用场景。
-
- CIColor:
- CIColor是Core Image结构中的色彩类,用于表明色彩信息。
- CIColor能够用来创立色彩方针,设置滤镜作用中的色彩参数。
-
- CIVector:
- CIVector是Core Image结构中的向量类,用于表明多维向量数据。
- CIVector能够用来设置滤镜作用中的向量参数,如方位、大小等。
-
Core Image 的 API 首要便是三类:
- CIContext 表明上下文,如 Core Graphics 以及 Core Data 中的上下文用于处理制作烘托以及处理托管方针一样,Core Image 的上下文也是完结对图画处理的详细方针。能够从其间获得图片的信息。
3. 代码示例
3.1 滤镜|含糊、锐化、色彩调整、边际检测 和 自界说滤镜
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
// 含糊处理
UIImage *applyBlurFilter(UIImage *image) {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@10 forKey:kCIInputRadiusKey];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultImage;
}
// 锐化处理
UIImage *applySharpenFilter(UIImage *image) {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CISharpenLuminance"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@0.5 forKey:kCIInputSharpnessKey];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultImage;
}
// 色彩调整
UIImage *applyColorAdjustmentFilter(UIImage *image) {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@1.2 forKey:kCIInputContrastKey];
[filter setValue:@0.5 forKey:kCIInputBrightnessKey];
[filter setValue:@0.8 forKey:kCIInputSaturationKey];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultImage;
}
// 边际检测
UIImage *applyEdgeDetectionFilter(UIImage *image) {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
CIFilter *filter = [CIFilter filterWithName:@"CIEdges"];
[filter setValue:ciImage forKey:kCIInputImageKey];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultImage;
}
// 自界说滤镜
UIImage *applyCustomFilter(UIImage *image) {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
// 自界说滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIColorMatrix"];
[filter setValue:ciImage forKey:kCIInputImageKey];
// 设置自界说参数
CIVector *RVector = [CIVector vectorWithX:1 Y:0 Z:0 W:0];
CIVector *GVector = [CIVector vectorWithX:0 Y:1 Z:0 W:0];
CIVector *BVector = [CIVector vectorWithX:0 Y:0 Z:1 W:0];
CIVector *AVector = [CIVector vectorWithX:0 Y:0 Z:0 W:1];
[filter setValue:RVector forKey:@"inputRVector"];
[filter setValue:GVector forKey:@"inputGVector"];
[filter setValue:BVector forKey:@"inputBVector"];
[filter setValue:AVector forKey:@"inputAVector"];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *resultImage = [UIImage imageWithCGImage
Swift示例:
import UIKit
import CoreImage
// 图画处理类
class ImageProcessor {
// 运用含糊滤镜
func applyBlurFilter(to image: UIImage) -> UIImage? {
if let ciImage = CIImage(image: image) {
let filter = CIFilter(name: "CIGaussianBlur")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(5.0, forKey: kCIInputRadiusKey)
if let outputImage = filter?.outputImage {
let context = CIContext()
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
}
}
}
return nil
}
// 运用锐化滤镜
func applySharpenFilter(to image: UIImage) -> UIImage? {
if let ciImage = CIImage(image: image) {
let filter = CIFilter(name: "CISharpenLuminance")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(0.5, forKey: kCIInputSharpnessKey)
if let outputImage = filter?.outputImage {
let context = CIContext()
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
}
}
}
return nil
}
// 运用色彩调整滤镜
func applyColorAdjustmentFilter(to image: UIImage) -> UIImage? {
if let ciImage = CIImage(image: image) {
let filter = CIFilter(name: "CIColorControls")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(1.2, forKey: kCIInputContrastKey)
filter?.setValue(0.8, forKey: kCIInputBrightnessKey)
filter?.setValue(0.5, forKey: kCIInputSaturationKey)
if let outputImage = filter?.outputImage {
let context = CIContext()
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
}
}
}
return nil
}
// 运用边际检测滤镜
func applyEdgeDetectionFilter(to image: UIImage) -> UIImage? {
if let ciImage = CIImage(image: image) {
let filter = CIFilter(name: "CIEdges")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
if let outputImage = filter?.outputImage {
let context = CIContext()
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
}
}
}
return nil
}
// 运用自界说滤镜
func applyCustomFilter(to image: UIImage) -> UIImage? {
if let ciImage = CIImage(image: image) {
// 自界说滤镜:将图画转为灰度图
let filter = CIFilter(name: "CIPhotoEffectMono")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
if let outputImage = filter?.outputImage {
let context = CIContext()
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
return UIImage(cgImage: cgImage)
}
}
}
return nil
}
}
// 运用示例
let image = UIImage(named: "example.jpg")!
let processor = ImageProcessor()
let blurredImage = processor.applyBlurFilter(to: image)
let sharpenedImage = processor.applySharpenFilter(to: image)
let colorAdjustedImage = processor.applyColorAdjustmentFilter(to: image)
let edgeDetectedImage = processor.applyEdgeDetectionFilter(to: image)
let customFilteredImage = processor.applyCustomFilter(to: image)
3.1 图画处理链|输入图画、滤镜作用、和输出图画
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
UIImage *applyFilterToImage(UIImage *inputImage) {
CIImage *ciImage = [[CIImage alloc] initWithImage:inputImage];
CIFilter *filter = [CIFilter filterWithName:@"CIPhotoEffectMono"];
[filter setValue:ciImage forKey:kCIInputImageKey];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
UIImage *filteredImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return filteredImage;
}
Swift示例:
// Swift示例:
import UIKit
import CoreImage
func applyFilterToImage(inputImage: UIImage) -> UIImage? {
if let ciImage = CIImage(image: inputImage) {
let filter = CIFilter(name: "CIPhotoEffectMono")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
if let outputImage = filter?.outputImage {
let context = CIContext(options: nil)
if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
let filteredImage = UIImage(cgImage: cgImage)
return filteredImage
}
}
}
return nil
}
3.1 图画剖析|人脸检测、特征辨认、色彩辨认、物体辨认
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
- (void)analyzeImage:(UIImage *)image {
CIImage *ciImage = [[CIImage alloc] initWithImage:image];
// 人脸检测
NSDictionary *options = @{CIDetectorAccuracy: CIDetectorAccuracyHigh};
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:options];
NSArray *faces = [faceDetector featuresInImage:ciImage];
for (CIFaceFeature *faceFeature in faces) {
NSLog(@"Detected face at %@", NSStringFromCGRect(faceFeature.bounds));
}
// 特征辨认
NSDictionary *featureOptions = @{CIDetectorImageOrientation: @(1)};
CIDetector *featureDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:featureOptions];
NSArray *features = [featureDetector featuresInImage:ciImage];
for (CIQRCodeFeature *feature in features) {
NSLog(@"Detected QR code with message: %@", feature.messageString);
}
// 色彩辨认
CIColor *averageColor = [ciImage valueForKey:@"inputImage"];
NSLog(@"Average color of the image: %@", averageColor);
// 物体辨认
NSDictionary *objectOptions = @{CIDetectorAccuracy: CIDetectorAccuracyHigh};
CIDetector *objectDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:objectOptions];
NSArray *objects = [objectDetector featuresInImage:ciImage];
for (CIRectangleFeature *objectFeature in objects) {
NSLog(@"Detected object at %@", NSStringFromCGRect(objectFeature.bounds));
}
}
Swift示例:
import UIKit
import CoreImage
class ImageAnalysis {
func analyzeImage(image: UIImage) {
if let ciImage = CIImage(image: image) {
let context = CIContext()
// 人脸检测
let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: context, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
let faces = faceDetector?.features(in: ciImage)
for face in faces as! [CIFaceFeature] {
print("Face bounds: (face.bounds)")
if face.hasLeftEyePosition {
print("Left eye position: (face.leftEyePosition)")
}
if face.hasRightEyePosition {
print("Right eye position: (face.rightEyePosition)")
}
}
// 特征辨认
let featureDetector = CIDetector(ofType: CIDetectorTypeRectangle, context: context, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
let features = featureDetector?.features(in: ciImage)
for feature in features as! [CIRectangleFeature] {
print("Feature bounds: (feature.bounds)")
}
// 色彩辨认
let colorDetector = CIDetector(ofType: CIDetectorTypeColor, context: context, options: nil)
let colors = colorDetector?.features(in: ciImage)
for color in colors as! [CIColorFeature] {
print("Detected color: (color.color)")
}
// 物体辨认
let objectDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: nil)
let objects = objectDetector?.features(in: ciImage)
for object in objects as! [CIQRCodeFeature] {
print("Detected QR code: (object.messageString ?? "")")
}
}
}
}
// 运用示例
let image = UIImage(named: "sampleImage")
let imageAnalysis = ImageAnalysis()
imageAnalysis.analyzeImage(image: image)
3.1 Metal功用优化
Objective-C示例:
// Objective-C示例:
#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
#import <CoreImage/CoreImage.h>
// 创立Metal设备和CIContext
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
CIContext *ciContext = [CIContext contextWithMTLDevice:device];
// 创立Metal纹路
MTKView *metalView = [[MTKView alloc] initWithFrame:CGRectZero device:device];
id<MTLTexture> metalTexture = metalView.currentDrawable.texture;
// 创立CIImage
CIImage *ciImage = [CIImage imageWithMTLTexture:metalTexture options:nil];
// 创立滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@(1.2) forKey:kCIInputContrastKey];
// 烘托并显现结果
CIImage *outputImage = [filter outputImage];
[ciContext render:outputImage toMTLTexture:metalTexture commandBuffer:nil bounds:outputImage.extent colorSpace:outputImage.colorSpace];
Swift示例:
// Swift示例:
import Metal
import MetalKit
import CoreImage
// 创立Metal设备和CIContext
let device = MTLCreateSystemDefaultDevice()
let ciContext = CIContext(mtlDevice: device!)
// 创立Metal纹路
let metalView = MTKView(frame: CGRect.zero, device: device)
let metalTexture = metalView.currentDrawable?.texture
// 创立CIImage
let ciImage = CIImage(mtlTexture: metalTexture!, options: nil)
// 创立滤镜
let filter = CIFilter(name: "CIColorControls")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(1.2, forKey: kCIInputContrastKey)
// 烘托并显现结果
if let outputImage = filter?.outputImage {
ciContext.render(outputImage, to: metalTexture!, commandBuffer: nil, bounds: outputImage.extent, colorSpace: outputImage.colorSpace)
}
3.1 实时预览
Objective-C示例:
// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
@interface ViewController : UIViewController <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic, strong) CIContext *ciContext;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
if (videoInput) {
[self.captureSession addInput:videoInput];
AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
[videoOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
[self.captureSession addOutput:videoOutput];
self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
self.previewLayer.frame = self.view.bounds;
[self.view.layer addSublayer:self.previewLayer];
[self.captureSession startRunning];
self.ciContext = [CIContext contextWithOptions:nil];
} else {
NSLog(@"Error setting up video input: %@", error);
}
}
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
// 运用滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@(1.2) forKey:kCIInputContrastKey];
CIImage *outputImage = [filter outputImage];
// 烘托到预览层
[self.ciContext render:outputImage toCVPixelBuffer:pixelBuffer];
}
@end
Swift示例:
// Swift示例:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
var captureSession: AVCaptureSession!
var previewLayer: AVCaptureVideoPreviewLayer!
var ciContext: CIContext!
override func viewDidLoad() {
super.viewDidLoad()
captureSession = AVCaptureSession()
guard let videoDevice = AVCaptureDevice.default(for: .video),
let videoInput = try? AVCaptureDeviceInput(device: videoDevice) else {
return
}
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
let videoOutput = AVCaptureVideoDataOutput()
videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
captureSession.addOutput(videoOutput)
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.frame = view.bounds
view.layer.addSublayer(previewLayer)
captureSession.startRunning()
ciContext = CIContext()
}
}
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
// 运用滤镜
let filter = CIFilter(name: "CIColorControls")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(1.2, forKey: kCIInputContrastKey)
if let outputImage = filter?.outputImage {
// 烘托到预览层
ciContext.render(outputImage, to: pixelBuffer)
}
}
}
六、Metal
1. 首要特点和功用
Metal是苹果公司推出的图形和核算结构,首要用于完结高功用的图形烘托和通用核算使命。以下是Metal结构的首要特点和功用:
-
- 低等级接口:
- Metal供给了
直接拜访GPU的低等级接口
,相比OpenGL和OpenCL等传统图形和核算结构愈加高效。 - 开发者能够愈加精细地操控图形烘托和核算流程,完结更高功用的图形处理和核算使命。
-
- 高功用图形烘托:
- Metal经过运用GPU的并行处理才能,完结高功用的图形烘托和作用处理。
- Metal支撑现代图形烘托技能,如
着色器编程
、纹路映射
、光照作用
、烘托三维场景
等,能够完结杂乱的图形烘托作用。
-
- 通用核算:
- Metal
不只用于图形烘托
,还能够用于通用核算使命,如机器学习
、图画处理
、物理模仿
等。 - Metal供给了
核算着色器和核算管线
,支撑GPU加快的通用核算,进步核算使命的功率和速度。
-
- 着色器编程:
- Metal运用着色器(Shader)来操控图形烘托和核算进程。
- 开发者能够运用Metal Shading Language(MSL)
编写着色器代码
,完结定制化的图形作用
和核算逻辑
。
-
- 指令缓冲区:
- Metal运用指令缓冲区(Command Buffer)来办理GPU指令的提交和履行。
- 开发者能够创立和提交指令缓冲区,操控GPU的操作流程,完结高效的图形烘托和核算使命。
-
- 资源办理:
- Metal供给了资源办理功用,用于办理GPU资源如缓冲区、纹路等。
- 开发者能够创立和办理各种GPU资源,优化资源的运用和同享,进步图形烘托和核算的功率。
-
- 多线程并发:
- Metal结构支撑多线程并发,能够在多个线程上一起履行图形烘托和核算使命。
- 开发者能够运用Metal的多线程特性完结并行处理,进步运用程序的功用和呼应速度。
-
- 内存办理:
- Metal供给了高效的内存办理机制,能够办理GPU资源和缓冲区的分配和开释。
- Metal的内存办理功用能够帮助开发者优化内存运用,避免内存泄漏和功用下降。
-
- 跨渠道支撑:
- Metal结构不只支撑iOS和macOS渠道,还能够在tvOS上运用,完结跨渠道的图形烘托和核算功用。
- Metal供给了共同的API和功用,便利开发者在不同渠道上完结一致的图形处理和核算使命
2. 中心类介绍
以下是Metal结构中一些中心类的介绍:
-
- MTLDevice:
- MTLDevice是Metal结构中表明GPU设备的类,用于创立Metal方针和办理GPU资源。
- 开发者能够经过MTLDevice创立其他Metal方针,如缓冲区、纹路等。
-
- MTLCommandQueue:
- MTLCommandQueue是Metal结构中的指令行列类,用于提交和履行GPU指令。
- 开发者能够将指令增加到MTLCommandQueue中,然后由GPU履行这些指令。
-
- MTLRenderPipelineState:
- MTLRenderPipelineState是Metal结构中的烘托管线状况类,用于装备图形烘托管线。
- 开发者能够经过MTLRenderPipelineState设置烘托管线的各个阶段,如极点着色器、片元着色器等。
-
- MTLBuffer:
- MTLBuffer是Metal结构中表明缓冲区的类,用于存储数据和传递给GPU。
- 开发者能够创立MTLBuffer方针来传递极点数据、纹路数据等到GPU进行处理。
-
- MTLTexture:
- MTLTexture是Metal结构中表明纹路的类,用于存储和处理图画数据。
- 开发者能够创立MTLTexture方针来加载纹路数据,用于图画处理和烘托。
-
- MTLComputePipelineState:
- MTLComputePipelineState是Metal结构中的核算管线状况类,用于装备核算使命。
- 开发者能够经过MTLComputePipelineState设置核算使命的各个阶段,如核算内核函数等。
- Metal结构供给了直接拜访GPU的才能,能够完结高功用的图形烘托和核算使命。经过这些中心类,开发者能够运用Metal结构完结杂乱的图形烘托、核算使命和图形作用,为运用程序供给愈加流通和高功用的图形处理才能。
3. 代码示例
经过后期的文章篇幅打开介绍…
七、GPUImage
1. 首要特点和功用
GPUImage是一个根据OpenGL ES 2.0的开源图画处理结构,支撑GPU加快,用于完结图画和视频处理的功用 以下是GPUImage结构的首要特点和功用:
-
- 滤镜(Filters):
- GPUImage供给了大量的滤镜作用,如
色彩调整
、含糊
、锐化
、边际检测
等。 - 开发者能够经过GPUImage供给的滤镜作用对
图画
和视频
进行实时处理
。 - 定制滤镜(Custom Filters):开发者能够经过编写自界说滤镜来扩展GPUImage的功用和作用,经过组合各种图画处理操作来创立个性化的滤镜作用,满足特定的处理需求。
-
- 处理链(Processing Chain):
- GPUImage支撑链式处理图画和视频数据,能够将多个滤镜作用串联起来,完结杂乱的处理流程,一起坚持高效的处理速度
- 每个处理进程都能够增加不同的滤镜作用。
- 开发者能够自界说处理链,完结杂乱的图画处理流程。
-
- 实时相机(Camera):
- GPUImage供给了相机类,能够直接从摄像头捕获实时图画数据、视频流。
- 开发者能够运用GPUImage的相机类完结实时滤镜作用和实时图画处理。
-
- 纹路(Textures):
- GPUImage运用OpenGL纹路来处理图画数据,进步处理功率和功用。
- 开发者能够运用GPUImage的纹路处理功用完结高效的图画处理和烘托。
-
- 实时处理(Real-time Processing):
- GPUImage支撑实时处理图画和视频流,能够在
实时视频流中运用滤镜作用
,完结实时的图画处理和增强
。 - 开发者能够运用GPUImage完结实时的图画处理作用,为运用程序增加更多的视觉吸引力
-
- 跨渠道支撑:
- GPUImage不只支撑iOS渠道,还支撑Android渠道和桌面渠道,能够完结跨渠道的图画处理运用开发。
-
- 易用性:
- GPUImage供给了简洁易用的API和文档,使开发者能够快速上手并完结各种图画处理需求,降低开发本钱和杂乱度。
-
- GPU加快:
- GPUImage运用GPU的并行核算才能来加快图画处理和滤镜作用的核算,进步处理速度和功率。
2. 中心类和协议介绍
中心类:
-
- GPUImageOutput:
- GPUImageOutput是一切输出类的基类,用于处理图画数据的输出。
- 其子类包含GPUImageFilter、GPUImagePicture等,用于完结不同的图画处理功用。
-
- GPUImageFilter:
- GPUImageFilter是图画滤镜的基类,用于完结各种图画处理滤镜作用。
- 开发者能够经过GPUImageFilter及其子类来运用各种滤镜作用,如含糊、锐化、色彩调整等。
-
- GPUImagePicture:
- GPUImagePicture用于将静态图画加载到GPU中进行处理。
- 能够经过GPUImagePicture加载UIImage或CGImage等静态图画数据,并传递给滤镜进行处理。
-
- GPUImageFramebuffer:
- GPUImageFramebuffer用于在GPU中存储图画数据的帧缓冲区。
- GPUImage处理图画数据时会运用帧缓冲区来存储中心结果,进步处理功率。
-
- GPUImageMovieWriter:
- GPUImageMovieWriter是用于将视频数据写入文件的类。
- GPUImageMovieWriter完结了GPUImageInput和GPUImageTextureOutput协议,能够接纳图画数据并将处理后的视频数据写入文件。
协议:
-
- GPUImageInput:
- GPUImageInput是输入类的协议,界说了接纳图画数据的办法。
- 一切需求接纳图画数据的类都需求完结GPUImageInput协议,以便接纳和处理图画数据。
-
- GPUImageTextureOutput:
- GPUImageTextureOutput是输出纹路的协议,用于输出处理后的纹路数据。
- 完结了GPUImageTextureOutput协议的类能够将处理后的纹路数据输出到其他当地,如屏幕、纹路等。
3. 代码示例
经过后期的文章篇幅打开介绍…
八、OpenGL ES
1. 首要特点和功用
OpenGL ES(OpenGL for Embedded Systems)是一种用于嵌入式体系的轻量级版本的OpenGL图形库,常用于移动设备和嵌入式体系中的图形烘托。以下是OpenGL ES的中心关键:
-
- 跨渠道性:
- OpenGL ES是跨渠道的图形API,能够在多种移动设备和嵌入式体系上运用,如iOS、Android、嵌入式Linux等。
-
- 硬件加快:
- OpenGL ES运用GPU硬件加快进行图形烘托,供给高功用的图形处理才能,适合移动设备和嵌入式体系的资源限制环境。
-
- 上下文办理:
- OpenGL ES运用上下文(Context)来办理图形状况和资源,包含
着色器程序
、纹路
、缓冲区
等。 - 开发者需求创立和办理OpenGL ES上下文,以便进行图形烘托和操作。
-
- 图形烘托:
- OpenGL ES支撑各种图形烘托功用,包含
极点处理
、片元处理
、纹路映射
、着色器编程
等,能够完结各种杂乱的图形作用。 - 着色器编程:
- OpenGL ES运用着色器(Shader)来界说图形烘托的核算进程,包含
极点着色器
和片元着色器
。 - 开发者能够编写
自界说的着色器程序
,用于完结各种图形作用和烘托算法。
- OpenGL ES运用着色器(Shader)来界说图形烘托的核算进程,包含
- 纹路映射:
- OpenGL ES支撑纹路映射(Texture Mapping),用于将纹路映射到几何图形外表,完结丰厚的纹路作用和贴图功用。
- 开发者能够加载纹路数据并将其映射到几何图形上,完结丰厚的纹路作用。
-
- 缓冲区方针:
- OpenGL ES运用缓冲区方针(Buffer Object),包含
极点缓冲区
、索引缓冲区
等来存储极点数据
、索引数据
等。 - 开发者能够创立和办理缓冲区方针,
存储和传递
图形数据,供给给GPU进行图形烘托
-
- 深度测验和混合:
- OpenGL ES支撑深度测验和混合功用,能够完结
透明作用
、深度排序
等,进步图形烘托的真实感和传神度。 - 多重采样抗锯齿:
- OpenGL ES支撑多重采样抗锯齿(MSAA),能够减少图形烘托中的锯齿现象,进步图形质量。
-
- 光照和原料:
- OpenGL ES支撑光照和原料(Lighting and Material),用于
模仿光照
作用和物体外表的原料特性
。 - 开发者能够经过设置光照参数和原料特点来完结传神的光照作用。
-
- 烘托管线:
- OpenGL ES运用烘托管线(Rendering Pipeline)来处理图形烘托进程,包含极点处理、几何处理、光栅化等阶段。
- 开发者能够装备烘托管线的各个阶段,以完结定制的图形烘托作用。
2. 中心类介绍
-
- GLKView:
- GLKView是OpenGL ES结构中用于显现OpenGL内容的视图类。
- GLKView供给了一个便利的办法来在iOS运用中显现OpenGL烘托的内容。
-
- GLKViewController:
- GLKViewController是OpenGL ES结构中的视图操控器类,用于办理OpenGL烘托和视图的交互。
- GLKViewController能够处理烘托循环、用户交互等使命,简化OpenGL ES运用程序的开发。
-
- GLKBaseEffect:
- GLKBaseEffect是OpenGL ES结构中的根本作用类,用于完结简略的烘托作用。
- GLKBaseEffect供给了一些根本的烘托作用,如色彩、光照、纹路等。
-
- GLKTextureLoader:
- GLKTextureLoader是OpenGL ES结构中的纹路加载器类,用于加载和办理纹路数据。
- GLKTextureLoader能够从文件、内存等来历加载纹路数据,便利在OpenGL ES运用中运用纹路。
-
- GLKMath:
- GLKMath是OpenGL ES结构中的数学库,用于处理矩阵、向量等数学运算。
- GLKMath供给了一些常用的数学函数和数据结构,便利在OpenGL ES运用中进行数学核算。
3. 代码示例
经过后期的文章篇幅打开介绍…
九、ARKit和Metal结构
1. ARKit
1.1 首要特点和功用
ARKit是苹果公司供给的增强实际(AR)结构,用于在iOS设备上完结增强实际体会。以下是ARKit的首要特点和功用:
-
- 环境感知:
- ARKit能够经过
摄像头
和传感器
感知设备周围的环境,包含平面
、笔直面
、光照
、特征点
等。 - ARKit供给了环境感知的功用,用于辨认和追寻实际国际中的物体和场景。
-
- 盯梢技能:
- ARKit支撑视觉惯性里程计(Visual-Inertial Odometry)和根据特征点的盯梢技能。
- ARKit能够实时追寻设备的
方位
和方向
,完结精确的虚拟物体叠加在实际国际中。
-
- 虚拟内容叠加:
- ARKit能够将虚拟内容叠加到设备摄像头捕捉的实际国际中,完结虚拟物体的
显现
和交互
-
- 场景了解:
- ARKit能够了解设备所处的场景,包含平面检测、光照估计等。
- ARKit能够检测水平缓笔直平面,辨认光照条件,为虚拟物体的烘托供给更真实的作用。
-
- 用户交互:
- ARKit支撑用户交互功用,能够经过
手势
、接触
、点击事情
等办法与虚拟内容进行交互,如移动
、旋转
、缩放
等操作。 - 用户能够经过手势操作和接触事情与增强实际场景进行交互,完结愈加沉溺式的体会。
-
- 平面检测:
- ARKit支撑平面检测功用,能够辨认
水平面
和笔直面
,用于在实际国际中放置虚拟物体。
-
- 光照估计:
- ARKit供给光照估计功用,能够根据环境光照条件调整虚拟内容的
亮度
和暗影
,使其与实际国际愈加融合。
-
- 耐久性体会:
- ARKit支撑耐久性体会,能够
保存
和恢复
虚拟内容在实际国际中的方位。 - 用户能够在不一起间点和场景中坚持共同的增强实际体会,提高用户体会的连贯性。
-
- 面部追寻:
- ARKit供给面部追寻功用,能够辨认和追寻用户的面部表情,用于完结
面部滤镜
、AR表情
等作用。
-
- 多设备协同:
- ARKit支撑多设备协同功用,能够完结多个设备之间的AR体会同步,如
同享虚拟场景
、多人协作
等。
1.2 中心类介绍
ARKit结构中一些中心类的介绍:
-
- ARSession:
- ARSession是ARKit结构中的会话类,用于办理AR体会的整个进程。
- ARSession担任追寻设备的方位和方向,辨认环境中的特征点,以及处理AR场景的烘托和更新。
-
- ARConfiguration:
- ARConfiguration是ARKit结构中的装备类,用于装备AR会话的参数和设置。
- ARConfiguration包含不同类型的装备,如ARWorldTrackingConfiguration、ARFaceTrackingConfiguration等,用于不同类型的AR体会。
-
- ARAnchor:
- ARAnchor是ARKit结构中的锚点类,用于表明在AR场景中的方位和方向。
- ARAnchor能够用于标记特定的方位或方针,以便在AR场景中进行定位和交互。
-
- ARSCNView:
- ARSCNView是ARKit结构中的场景视图类,用于显现AR场景和烘托3D内容。
- ARSCNView结合了SceneKit结构,能够便利地在AR场景中增加3D模型、动画等内容。
-
- ARPlaneAnchor:
- ARPlaneAnchor是ARKit结构中的平面锚点类,用于表明检测到的水平平面。
- ARPlaneAnchor能够用于在AR场景中辨认和盯梢水平外表,如地上、桌面等。
-
- ARHitTestResult:
- ARHitTestResult是ARKit结构中的射中测验结果类,用于检测AR场景中的交互射中结果。
- ARHitTestResult能够用于检测用户在AR场景中的点击、接触等交互操作。
经过这些中心类,开发者能够运用ARKit结构完结各种增强实际体会,包含追寻设备方位
、辨认环境特征
、烘托3D内容
等功用,为用户供给沉溺式的增强实际体会。
1.3 代码示例
本文暂不打开介绍,后边有额定的篇幅打开
2. VR = ARKit+Metal 中心关键:
结合ARKit和Metal完结VR(Virtual Reality)体会的中心关键包含以下几个方面:
-
- ARKit中的空间追寻:
- 运用ARKit进行空间追寻,能够完结设备在实际国际中的定位和追寻,为VR体会供给根底支撑。
- ARKit能够辨认环境中的特征点、平面和物体,用于定位虚拟内容的方位和方向。
-
- Metal中的图形烘托:
- 运用Metal进行高功用的图形烘托,能够完结流通的虚拟实际场景出现。
- Metal供给了直接拜访GPU的才能,能够完结杂乱的图形烘托和核算使命,为VR体会供给高功用的图形处理支撑。
-
- ARKit和Metal的集成:
- 将ARKit和Metal结合起来,能够完结在AR场景中烘托虚拟内容,与实际国际进行交互。
- 经过ARKit供给的空间追寻功用,将虚拟内容与实际国际对齐,再运用Metal进行图形烘托,完结沉溺式的VR体会。
-
- 交互和操控:
- 在ARKit+Metal的VR体会中,能够经过手势辨认、头部追寻等技能完结用户的交互和操控。
- 用户能够经过手势、头部运动等办法与虚拟内容进行交互,增强VR体会的沉溺感和互动性。
-
- 功用优化:
- 在完结ARKit+Metal的VR体会时,需求考虑功用优化,包含减少烘托推迟、优化图形质量、进步帧率等方面。
- 经过合理的功用优化办法,能够确保VR体会的流通性和稳定性。
3. 其它
本文首要针对官方自带的图形界面处理结构和比较盛行的GPUImage结构进行简略介绍。暂不对AR、VR等相关技能打开更多评论
十、Open CV、SpriteKit、Sence Kit
在iOS开发中,运用SpriteKit结构、Sence Kit结构 能够进行 2D、3D游戏开发。运用OpenCV能够进行核算机视觉处理开发。
1. Open CV
OpenCV 的 API 是 C++ 的。它由不同的模块组成,这些模块中包含范围极为广泛的各种办法,从底层的图画色彩空间转化到高层的机器学习工具。这儿供给一个入门PDF文档 下载入口。
运用 C++ API 并不是绝大多数 iOS 开发者每天都做的事,你需求运用 Objective-C++ 文件来调用 OpenCV 的函数。 也便是说,你不能在 Swift 或许 Objective-C 言语内调用 OpenCV 的函数。 这篇 OpenCV 的iOS 教程告诉你只要把一切用到 OpenCV 的类的文件后缀名改为.mm
就行了,包含视图操控器类也是如此。这么干或许能行得通,却不是什么好主意。正确的办法是给一切你要在 app 中运用到的 OpenCV 功用写一层 Objective-C++ 封装。这些 Objective-C++ 封装把 OpenCV 的 C++ API 转化为安全的 Objective-C API,以便利地在一切 Objective-C 类中运用。
走封装的路子,你的工程中就能够只在这些封装中调用 C++ 代码,然后避免掉许多让人头痛的问题,比方直接改文件后缀名会由于在过错的文件中引用了一个 C++ 头文件而产生难以追寻的编译过错。
OpenCV 声明了命名空间cv
,因此 OpenCV 的类的前面会有个cv::
前缀,就像cv::Mat
、cv::Algorithm
等等。你也能够在.mm
文件中运用using namespace cv
来避免在一堆类名前运用cv::
前缀。但是,在某些类名前你必须运用命名空间前缀,比方cv::Rect
和cv::Point
,由于它们会跟界说在MacTypes.h
中的Rect
和Point
相冲突。虽然这仅仅个人偏好问题,我仍是偏向在任何当地都运用cv::
以坚持共同性。
一般讲的OpenCV是根据CPU的,相关材料和支撑也是最完善的。当然,也有根据GPU模块,但供给的接口非常坑爹,适当一部分不支撑浮点类型(像histogram、integral这类常用的都不支撑);又如,遇到阈值判别的当地,就必须传回cpu处理,由于gpu函数都是并行处理的,每改写完一个算法模块,就测验一下运行功率,有的时分是振奋人心,有的时分则是当头棒喝——比CPU还慢。概况可参阅 这儿。
2. SpriteKit、Sence Kit
关于寻找游戏引擎的开发者来说,Metal 不是最佳挑选。苹果官方的的Scene Kit(3D) 和Sprite Kit(2D) 是更好的挑选。这些 API 供给了包含物理模仿在内的更高等级的游戏引擎。
另外还有功用更全面的 3D 引擎,例如 Epic 的Unreal Engine或Unity,二者都是跨渠道的。运用这些引擎,你无需直接运用 Metal 的 API,就能够从 Metal 中获益。
2.1 2D烘托 — SpriteKit
SpriteKit 让开发者能够开发高功用、省电节能的 2D 游戏。在 iOS 8 中,咱们新添了多项增强功用,这将使 2D 游戏体会愈加精彩。这些新技能有助于使游戏角色的动作愈加自然,并让开发者能够更轻松地在游戏中加入力场、检测磕碰和生成新的灯光作用。
2.2 3D烘托 — SceneKit
SceneKit 专为休闲 3D 游戏而规划,可让开发者烘托 3D 游戏场景。SceneKit 内置了物理引擎、粒子发生器和各种易用工具,能够轻松方便地为 3D 物体编写动作。不只如此,它还与 SpriteKit 完全集成,所以开发者能够直接在 3D 游戏中加入 SpriteKit 的资料。
3. 其它
本文首要针对官方自带的图形界面处理结构和比较盛行的GPUImage结构进行简略介绍。暂不对游戏、核算机视觉等相关技能打开更多评论
总结
本文首要针对官方自带的图形界面处理结构和比较盛行视频图层处理结构进行简略介绍:
- 体系自带结构
- UIKit
- Core Graphics
- Core Image
- Core Animation
- Metal
- 盛行的第三方结构
- GPUImage
- OpenGL ES
后边会有几篇文章针对这几大块,进行更详细的介绍
本文没有评论
- ARKit和Metal结构进行 XR开发(AR、VR)
- Open CV 核算机视觉开发
- SpriteKit、Sence Kit 游戏开发 若后边有时刻,会进行简略的了解,给自己一个知识储备