在本教程中,您将学习如何:
- 使用 AR Face Tracking 使用 TrueDepth 摄像头跟踪您的面部。
- 在您跟踪的脸上覆盖表情符号。
- 根据您做出的面部表情操纵表情符号。
入门
对于本教程,您需要一部带有前置 TrueDepth 摄像头的 iPhone。在撰写本文时,这意味着 iPhone X,但谁知道未来会带ios15来什么?
您可能已经使用本编辑器教程顶部或底部的下载材料链接下载了本教程的材料,并注意到没有启动项目。这不是一个错误。您将从头开始编写这个应用程序 – Emoji Bl编辑器下载ing!
启动 Xcode 并基于Single View App模板创建一个新项目并将其命名为Emoji Bling。
您应该做的第一件事是给默认值ViewController
一个更好的名称。在左侧的 Project navigator 中选择Viapple storeewController.swift 。
在标准编辑器中出现的代码中,右键单击类的名称,然Apple后从弹出的上下文菜单中ViewController
选择重构 ▸ 重命名。
将类的名称更改为Emoji索引的优缺点BlingViewController
并按Return或单apple id密码重置击蓝色的重命名按钮。
注意:有ios下载时ios系统重构过程会忘记重命名ViewController.ios应用商店swift文件。如果发生这种情况,只需在Finder中手动执行此操作,然后再次将文件添加到项目中。
既然您已经在EmojiBlingViewController.sw编辑器小说ift中闲逛,apple store请继续将以下导入添加到顶部:
导入ARKit
毕竟,Apple您是在制作增强现实应用程序,对吧?
接下来,在Main.storyboard中,选择**Emoji Bling View Controller中的顶级View,ios模拟器将类更改为ARSCNView索引失效的几种情况。
ARSCNView
是使用SceneKit内容显示增强ios系统现实体验的特殊视app store图。它可以显示相机馈送和显示器SCNNod面试问题e
。
将顶层视图更改为 后ARSCNView
,您希望为您的类IBOutlet
中的视图创建一个。EmojiBlingViewController
为此,请通过单击带有互锁环的按钮来调出助手编辑器。
这应该会自动在助手编辑器中显示EmojiBlingViewController.swift的内容。如果没有,您可以在项目导航器中按住 Option 键单击它以在其中显示它。
现在,从情节提要中按住 Control 并拖动到**EmojiBlingViewController.swift中类定义的正下方,并命名为 outlet。ARSCNV编辑器iew`索引失效的几种情况`EmojiBlingViewController``sceneView
在构建和运行之前,需要一些代码来显示相机源并开ios是什么意思始跟踪您的面部面试问题。iOS
在EmojiBlingViewControlle编辑器和ide的区别r.swift中,将以下编辑器软件函数添加到EmojiBlingViewController
类中:
覆盖 函数 viewWillAppear(_ 动画:布尔){
超级.viewWillAppear(动画)
// 1
让配置= ARFaceTrackingConfiguration ()
// 2
sceneView.session.run(配置)
}
覆盖 函数 viewWillDisappear(_ 动画:布尔){
超级.viewWillDisappear(动画)
// 1
场景视图.session.pause()
}
在视图出现之前,您:
- 创建配置以跟踪人脸。
- 使用.
ARSession
_ARSCNView
在视图消失之前,请确保:
- 暂停 AR 会话。
到目前为止,此代码存在一个很小的问题。ARFaceTrackingConfiguration
仅适用于配备前置原深感摄像头的手机。您需要确保在做任何事情之前检查这一点。
在同一个文件中,将以下内容添加到vios15iewDidLo面试技巧ad()
应该已经存在的函数末尾面试:
guard ARFaceTrackingConfiguration .isSupported else {
fatalError(“此设备不支持人脸跟踪”)
}
有了这个,您检查以确保设备支持面部跟踪(即,具有前置 TrueDepth 摄像头),否则停止。这不是处理这个问题的优雅方式,apple watch但由于这ios系统个应用程序只进行面部跟踪,所以其他任何事情都毫面试自我介绍简单大方无意义!
在运行您的应用程序之前,编辑器英语您还需要在Inf索引图o.plist 中指定需要使用相机权限的原因。
在 Project navigator 中选择Info.plist并添加一个带有 键的条目PriviOSacy - Camera Usage Description
。它应该默认为 typ索引的作用eString
。对于该值,请键入EmojiBling 需要访问您的相机才能跟踪您的面部。索引的作用
最后。是时候构建和运行这只小狗了……呃……应用程序……appuppy?
当你这样做时,你应该看到ios14.4.1更新了什么你美丽的笑脸正盯着你。
好的,足够的鸭面。你还有更多的工作要做!
注意:此项目的某些构建步骤可能需要很长时间。虽然看起来 Xcode 已经去喝咖啡了,但它可能还没有,你只需要耐Apple心等待它。
面锚和几何形状
您已经看到了Aapple tvRFaceTrackingConfiguration
,它用于配置设备以使用 TrueDepth 摄像头跟踪您的面部。凉爽的。
但是Apple您还需要了解有关面部跟踪的哪些信息?
您将很快使用的三个非ios15常重要的类ARFaceAnchor
是ARFaceGeomet面试自我介绍ry
和ARSCNFaceGeometry
。
ARFaceAnchor
继承自ARAnchor
。如果你以前用ARKit做过任何事情,你就会知道ARAnchor
s 是它如此强大和简单的原因。它们是ARKit跟踪的现实世界中的位置,当您移动手机时它们不会移动。ARFaceAnchor
s 还包括有关人脸的信息,例如拓扑和表情。
ARFaceGeom索引etry
听起来很像。vertices
它是包含和的人脸的 3D 描述textureCoordinates
。
ARSCNFaceGeom索引的作用etry
使用来自 an 的数据ARFaceGeometry
来创建 aSCNGeometry
,它可以用来创建SceneKit节点——基本上就是你在屏幕上看到的。
好的,够了。是时候使用其中一些类了。回到编码!
添加网格蒙版
从表面上看,您似乎只打开了前置摄像头。但apple id是,您没有看到的是您的 iPhone 已经在跟踪您的脸部。毛骨悚然,小 iPhone。
看看 iPhone 正在跟踪什么不是很好吗?多么巧合,因为这正是你接下来要做的!
Emo面试自我介绍简单大方jiBlingViewController
在类定义的右大括号后添加以下代码:
// 1 个
扩展 EmojiBlingViewController : ARSCNViewDelegate {
// 2
func 渲染器( _renderer : SCNSceneRenderer , nodeFor anchor : ARAnchor ) -> SCNNode ? {
// 3
guard let device = sceneView.device else {
return nil
}
// 4
让faceGeometry = ARSCNFaceGeometry (device: device)
// 5
let node = SCNNode (geometry: faceGeometry)
// 6
node.geometry ? .firstMaterial ? .fillMode = .lines
// 7
返回节点
}
}
在此代码中,您:
- 声明
EmojiBlingViewController
实现ARSCNViewDelegate
协议。 -
renderer(_:nodeFor:)
从协议中定义方法。 - 确保用于渲染的 Metal 设备不为零。
- 创建要由 Metal 设备渲染的面几何体。
- 基于app store人脸几何创建一个SceneKit节点。
- 将节点材质的填充模式设置为仅线条。
- 返回节点。
注意:ARSCNFaceGeometry
仅在使用 Metal 渲染的SceneKit视图中可用,这就是为什么您需要在初始化期间传入 Metal 设备的原因。此外,此代码仅在您针对真实硬件时才会编译;如果您索引是什么意思以模拟器为目标,它将无法编译。
在运ios16行它之前,您需要将此类设置为ARSCNView
的委托。
在viewDidLoad()
函数末尾添加:
场景视图.delegate = self
好的,是每个人最喜欢的步骤的时间了。构建并运行该应用程序!
更新网格蒙版
您是否注意到网格蒙版有点……静态?当然,当您移动头部时,它会索引的优缺点跟ios15踪您的面部位置并随之移动,但是当您眨眼或张开嘴时会发生什么?没有。
多么令人失望。apple id密码重置
幸运的是,这很编辑器下载容易解决。您只需要添加另一种ARSCapple id密码重置NViewDelegate
方法!
在ARSCNViewDios是苹果还是安卓elegate
扩展的末尾,添加以下方法:
// 1
func 渲染器(
_ 渲染器:SCNSceneRenderer,
didUpdate 节点:SCNNode,
用于 锚点:ARAnchor){
// 2
guard let faceAnchor = anchor as? ARFaceAnchor,
让faceGeometry = node.geometry为? ARSCNFaceGeometry 其他{
返回
}
// 3
faceGeometry.update(来自:faceAnchor.geometry)
}
在这里,你:
- 定义协议方法的
didUpdate
版本。renderer(_:didUpdate:for:)
- 确保正在更新的锚点是 an
ARFaceAnchor
并且节点的几何形状是ARSCNFaceGeome编辑器和ide的区别t面试自我介绍一分钟ry
. -
ARSCNFaceGeometry
使用ARFaapple payceAnchor
‘s更新ARFaceGeometry
现在,当您构建并运行时,您应该会看到网格蒙版形式并更改以匹配您的面部表情。
表情金光闪闪索引失效的几种情况
如果您还没有这样做,请继续通过教程顶部或底部的按钮下载本教程的材料。
在里面,你会发现一个名为SuperUseful索引图Code的文件夹,里面有一些 Swift 文件。将它们拖到 EmojiBlingViewController.swift下方的项目中索引的作用。选择Copy items if needed,索引页是哪一页Create groups,并确保选择Emoji Bling目标
StringExtension.swift包含一个String
可以将 a 转换String
为 a的扩展UIImage编辑器135
。
EmojiNode.swift包含一个SCNNode
被调用的子类EmojiNode
,它可以渲染一个String
.它需要一个 s 数组,Str索引符号ing
并且可以根据需要循环它们。
随意探索这两个文件,但深入了解此代码的工作原理超出了本教程的范围。
有了这些,是时候增加你的鼻子了。并不是说它有什么问题。你已经是这么漂亮的人了。:]
在EmojiBlingViewController
类的顶部,定义以下常量:
让noseOptions = [ "" , "" , "" , " " ]
数组末尾的空白区域是为了让您可以选择清编辑器手机版除鼻子工作。如果编辑器怎么打开您愿意,可以随意选择其他鼻子选项。
接下来,将以下辅面试常见问题及回答技巧助函数添加到您的EmojiBlingViewController
类中:
func updateFeatures ( for node : SCNNode , using anchor : ARFaceAnchor ) {
// 1
let child = node.childNode(withName: "nose" , recursively: false ) as? 表情符号节点
// 2
let vertices = [anchor.geometry.vertices[ 9 ]]
// 3 个
孩子?.updatePosition(用于:顶点)
}
在这里,你:
- 搜索
node
名字为“nose”且属于 type 的孩子EmojiNode
-
ARFaceGeometry
从 的属性中获取索引 9 处的顶点ARFaceAnchor
并将其放入数组中。 - 使用成员方法
EmojiNode
根据顶点更新其位置。app store此upd索引超出了数组界限什么意思atePosition(forapple官网:)
方法采用顶点数组并将节面试技巧点的位置设置为其中心。
注意:那么索引 9 是从哪里来的?这是索引符号一个神ios15奇的数字。其中ARFaceGeometry
有 1220 个顶点,索引 9 在鼻子上。ios越狱这目前有效,但稍后您将简要阅读使用这些索引常量的危险以及您可以做些什么ios模拟器。
使用辅助函数来更新单个节点可能看起来很愚蠢,但稍后您将加强此函数并索引严重依赖它。
现在你只需要添加一个EmojiNode
到你的人脸节点。Applereturn
在方法中的语句之前添加以下代码renderer(_:nodeFor:)
:
// 1 个
节点几何?.firstMaterial ? .透明度= 0.0
// 2
让noseNode = EmojiNode (with:noseOptions)
// 3
鼻子节点名称= "鼻子"
// 4
node.addChildNode(noseNode)
// 5
updateFeatures(for: node, using: faceAnchor)
在此代码中,您:
- 通过使其透明来ios越狱隐藏网格蒙版。
-
EmojiNode
使用您定义的鼻子选项创建一个。 - 命名鼻子节点,以便以app id注册后可以找到。
- 将鼻子节点添加到面编辑器小说部节点。
- 调用重新定位面部特索引超出了数组界限什么意思征的辅助函数。
您会注意到编译器错误,因为face索引页是哪一页Anchor
未定义。要解决此问题,guard
请将同一方法顶部的app store语句更改为以下内容:
守卫 让faceAnchor =锚为? ARFaceAnchor ,
let device = sceneView.device else {
return nil
}
在运行您的应用程序之前,您还应该做一件事。在中,在右大ios15括号之前renderer(_:didUpdate:for:)
添加一个调用:updateFeat索引符号ures(for:using:)
updateFeatures(for: node, using: faceAnchor)
这将确保当您抬起脸或摆动鼻子时,表情符号的位置会随着您的动作而更新。
现在是构建和运行的时候了Apple!
改变金光闪闪
现在,那个新鼻子很好,但也许有些日子你想换个鼻子?
当您点击它们时,您将添加代码以循环浏览您的鼻子选项。
打开MaApplein.storyboard并找到Tap Gestapple storeure Recogniapp storezer。您可以通过打开故事ios模拟器板右上角的对象库来ios系统找到它。
将其拖到ARSCNView
您的视图控制器中。
Mai编辑器哪个好用n.storyboard在标准编辑器索引的作用**中仍然打开,像以前一样在助手编辑器中打开EmojiBlingViewController.swift 。现在按住编辑器软件 Control 并从Tap Gesture Recognizer拖动到您的主类。EmojiBlin编辑器软件gViewController
释放鼠标并app id注册添加一个名为.handleTap``UITapGestureRecog编辑器135nizer
注意apple store:由于某种索引符号原因,您只能按住索引图 Control 并拖动到原始类定义而不是扩展。但是,如果您愿意,您可以稍后将生成的存根剪切索引失效的几种情况并粘贴到扩展中。
现iOS在,将以下代码添加到您的新handleTap(_:)
方法中:
// 1
let location = sender.location(in: sceneView)
// 2
let results = sceneView.hitTest(location, options: nil )
// 3
if let result = results.first,
let node = result.node as? 表情符号节点{
// 4
node.next()
}
在这里,你:
- 获取水龙头在
sceneView
. - 执行命中测试以获取点击位置下的节点列表。
- 在点击位置获取第一个apple官网(顶部)节点并确保它是
EmojiNode
. - 当您创建它时,调用该
next()
方法以切换EmojiNode
到您使用的apple store列表中的下一个选项。
现在是时候了。最美妙的时光。构建和运行时间。去做吧!索引失效当你点击你的ios15表情符号鼻子时,它会改变。
更多表情符号金光闪闪
有了对 emoji blapple paying 的新口味,索引符号是时候添加更多的 bling 了。
在EmojiBlingViapple id密码重置ewController
类的顶部,在常量下方添加以下noseOptions
常量:
让eyeOptions = [ "" , "" , "" , "" , "⚽️" , "" , " " ]
let mouthOptions = [ "" , "" , "❤️" , " " ]
让hatOptions = [ "" , "" , "" , "⛑" , "" , " "]
再一次,如果您愿意,可以随意选择不同的表情符号。
在您的renderer(_:nodeFor:)
方法中,索引图在对 的调用上方upda编辑器teFeatures(for:using:)
,添加其余的子节点定义:
让leftEyeNode = EmojiNode (with: eyeOptions)
leftEyeNode.name = "leftEye"
leftEyeNode.rotation = SCNVector4 ( 0 , 1 , 0 , GLKMathDegreesToRadians ( 180.0 ))
node.addChildNode(leftEyeNode)
让rightEyeNode = EmojiNode (with: eyeOptions)
rightEyeNode.name = "右眼"
node.addChildNode(rightEyeNode)
让mouthNode = EmojiNode (with:mouthOptions)
mouthNode.name = "嘴"
node.addChildNode(mouthNode)
让hatNode = EmojiNode (with: hatOptions)
hatNode.name = "帽子"
node.addChildNode(hatNode)
这些面索引页是哪一页部特征节点就像noseNode
您已经定义的一样。唯一略有不同的是设置left索引图EyeNode.rotation
.这会导致节点绕 y 轴旋转 180 度。由于EmojiNode
s 从两侧可见,这基本上反映了左眼的表情符号。
如果您现在运行代码,您会注意到所有新表情符号都位于您脸部的中心,并且不面试会随着您的脸部旋转。这是因为该方法到目前为止updateFeatures索引(for:using:)
只更新了*鼻子。*其他一切都放在头部的原点。
你真的应该解决编辑器手机版这个问题!
在文件顶部,在您的下方添加以下常量hatOptapple id密码重置ions
:
让features = [ "nose" , "leftEye" , "rightEye" , "mouth" , "hat" ]
让featureIndices = [[ 9 ], [ 1064 ], [ 42 ], [ 24 , 25 ], [ 20 ]]
features
是您为每个特征指定的节点名称的数组,并且是对应于这些特征featureIndices
的顶点索引(还记得幻数吗?)。ARFaceGeometry
您apple id密码重置会注意到“嘴”有两个与之关联的索引。由于张开的嘴巴是网状面具索引的优缺点上的一个洞,因此定位嘴巴表情符号的最佳方法是平均上唇和下唇的位置。
注意:索引超出矩阵维度功能的硬编码索引是技术债务的潜在来源。目前,anARFaceGeometry
有app id注册 1220 个顶点,但如果 Apple 决定它想要高分辨率会怎样?突然间,这些索引可能不再符合您的预期。ios14.4.1更新了什么一种可能的稳健解决方案是ios系统使用 Apple 的 Vision 框架来面试自我介绍简单大方初步检测面部特征并将其位置映射到最近的顶点ARFaceGeometry
接下来,将您当前的实现替换updateFeatures(for:using:)
为以下内容:
// 1
for (feature, indices) in zip (features, featureIndices) {
// 2
let child = node.childNode(withName: feature, recursive: false ) as? 表情符号节点
// 3
let vertices = indices.map { anchor.geometry.vertices[ $0 ] }
// 4 个
孩子?.updatePosition(用于:顶点)
}
这看起来非常相似,但有一些变化需要考虑。在此编辑器英语代码中,您:
- 循环遍历您在类顶部定义的
features
and 。featureIndexes
- 按特征名称查找子节点并确保它是
EmojiNode
. -
ARFaceGeometry
使用 的属性将索引数组映射到顶点数组ARFaceAnchor
。 - 使用这些顶点更新编辑器和ide的区别子节点面试问题大全及答案大全的位置。
开始构建并运行您的应用程序。你知道你想。
混合形状系数
ARFaceAnchor
不仅包含面部ios越狱的几何形状。它还包含混合形状系数。混合形状系数描述了您的面部表现出多ios16少表情。系数范围从 0.0(无表达式)到 1.0(最大表达式)。
例如,当您的脸颊脸颊松弛时,以及当您的脸颊像海豚一样膨胀到最大的时候,ARFaceAnchor.BlendShapeLocation.cheek索引的作用Puff
会记录下来!这……厚皮。0.0``1.0
目前有 52 个混合形状因子可供选择。在 Apple 的官方文档中查看它们。
用你的脸控制表情符号!
在阅读上一节关索引失效于混合形状的内容时,您是否想知道是否索引失效的几种情况可以使用它们来展ios14.4.1更新了什么示您的表情?
左眼眨眼
在updateAppleFeatures(for:using:)
中,就在for
循环的右边大括号之前,添加以下代码:
// 1
功能开关{
// 2
案例“左眼”:
// 3
让 scaleX = child ? .scale.x ?? 1.0
// 4
让 eyeBlinkValue = anchor.blendShapes[.eyeBlinkLeft] ? .floatValue ?? 0.0
// 5 个
孩子?.scale = SCNVector3 (scaleX, 1.0 - eyeBlinkValue, 1.0 )
// 6
默认:
休息
}
在这里,你:
-
switch
在功能名称上使用声明。 -
caios越狱se
为实施leftEye
。 - 默认保存为 1.0 的面试节点的 x 比例。
-
eyeBlinkLeft
如果未找到,则获取混合形状系数并默认为 0.0(未隐藏)。 - 根据混合形状因子修改节点的 y 比例。
- 默认设置
case
以使switch
特工无遗体。
很简面试单,对吧?制造并运行!
右眼眨眼
这将与左眼的代码非常相似。将以下内容添编辑器怎么打开加case
到相同的switch
语句中:
案例“右眼”:
让 scaleX = child ? .scale.x ?? 1.0
让 eyeBlinkValue = anchor.blendShapes[.eyeBlinkRight] ? .floatValue ?? 0.0
孩子?.scale = SCNVector3 (scaleX, 1.0 - eyeBlinkValue, 1.0 )
再次,并运行您索引的优缺点的应用程序,您应该可以用眼睛看到了!
开杰
现在,在应用程序中,张开嘴巴面试巴,巴巴表情符号会暂停在嘴巴巴apple pay之间,面试技巧和话术大全但有点覆盖嘴巴。这有点,如果你不是说呢?
你要解决这个问题。现索引的优缺点在将下面的内容添加case
到同一个switch
语句中:
案例“嘴”:
让jawOpenValue = anchor.blendShapes[.jawOpen] ? .floatValue ?? 0.2
孩子?.scale = SCNVector3 ( 1.0 , 0.8 + jawOpenValue, 1.0 )
在这里,是jawOpen
混合的形状,但它适合0.0
你吗?但您可以使用一下吗?可靠。这就是你使用的。ios是苹果还是安卓1.0``mouthClose``.jawOpen
继续您的最后一次制作并运行您的应用程序,并运行于您的创作。
结论
您可以使用教程中的所有面试技巧和注意事项代码部分下载最终项目。
这里也推荐一些面试相关的内容!
-
① BAT等各个大厂iOS面试真题+答案大全
-
②ios15 iO面试自我介绍一分钟S中高级开发必看的热门书籍(经ios模拟器典必看)
-
③ iOS开发高级面试”简历制作”指导
-
④ iOS面试流程到基础知识大全