线上地址
https://itunes.apple.com/cn/app/weare/id1304227680?mt=8
开源地址
https://github.com/SherlockQi/HeavenMemoirs

技术点

AR初始化

在新建项目时可以直接创建 AR 项目, xcode 会创造一个 AR 项目的模板.

也可以创建普通的项目,在需要实现 AR 功能的控制器中实现如下代码进行初始化.

   import ARKitlet sceneView = ARSCNView()override func viewDidLoad() {super.viewDidLoad()sceneView.frame = view.boundsview.addSubview(sceneView)sceneView.delegate = selfsceneView.showsStatistics = true// 创建一个场景,系统默认是没有的let scene = SCNScene()sceneView.scene = scene//不允许用户操作摄像机sceneView.allowsCameraControl = false//抗锯齿sceneView.antialiasingMode = .multisampling4X}override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)let configuration = ARWorldTrackingConfiguration()sceneView.session.run(configuration)}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)sceneView.session.pause()}

添加节点

        //我使用的是 SCNPlane 来充当相框,也可以使用"厚度"很小的 SCNBoxlet photo = SCNPlane(width: 1, height: 1)//photo.cornerRadius = 0.01let image = UIImage(named: "0")//纹路可以使图片,也可以是颜色photo.firstMaterial?.diffuse.contents = image//photo.firstMaterial?.diffuse.contents = UIColor.redlet photoNode = SCNNode(geometry: photo)//节点的位置let vector3 = SCNVector3Make(-1, -1, -1) photoNode.position = vector3sceneView.scene.rootNode.addChildNode(photoNode)
         let text = SCNText(string: "文字", extrusionDepth: 0.1)text.font = UIFont.systemFont(ofSize: 0.4)let textNode = SCNNode(geometry: text)textNode.position = SCNVector3Make(0,0, -1)//文字的图片/颜色text.firstMaterial?.diffuse.contents = UIImage(named: color)sceneView.scene.rootNode.addChildNode(textNode)
可供选择的几何图形
SCNText 文字
SCNPlane 平面
SCNBox 盒子
SCNPyramid 锥形
SCNSphere 球
SCNCylinder 圆柱
SCNCone 圆锥
SCNTube 圆筒
SCNCapsule 胶囊
SCNTorus 圆环
SCNFloor 地板
SCNShape 自定义

全景图实现

想象自己站在一个球的球心处,球的内表面涂着壁画,那么是不是就实现了全景图.
所以用一个Sphere 节点包裹着相机节点(也就是0位置节点),再设置Sphere节点的内表面纹理,就实现了功能.let sphere = SCNSphere(radius: 15)let sphereNode = SCNNode(geometry: sphere)sphere.firstMaterial?.isDoubleSided = truesphere.firstMaterial?.diffuse.contents = imagesphereNode.position = SCNVector3Zeroscene.rootNode.addChildNode(sphereNode)

播放视频

            let height:CGFloat = CGFloat(width) * videoSize.height/videoSize.widthlet box = SCNBox(width: width, height: height, length: 0.3, chamferRadius: 0)boxNode.geometry = box;boxNode.geometry?.firstMaterial?.isDoubleSided = trueboxNode.position = SCNVector3Make(0, 0, -5);box.firstMaterial?.diffuse.contents = UIColor.redself.scene.rootNode.addChildNode(boxNode);let avplayer = AVPlayer(url: url)avplayer.volume = rescoucceConfiguration.video_isSilence ? 0.0 : 3.0videoPlayer = avplayerlet videoNode = SKVideoNode(avPlayer: avplayer)NotificationCenter.default.addObserver(self, selector: #selector(playEnd(notify:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)videoNode.size = CGSize(width: 1600, height: 900)videoNode.position = CGPoint(x: videoNode.size.width/2, y: videoNode.size.height/2)videoNode.zRotation = CGFloat(Float.pi)let skScene = SKScene()skScene.addChild(videoNode)skScene.size = videoNode.sizebox.firstMaterial?.diffuse.contents = skScenevideoNode.play()

粒子效果

            /*particleName = "bokeh.scnp"particleName = "rain.scnp"particleName = "confetti.scnp"**/particleSytem = SCNParticleSystem(named: particleName, inDirectory: nil){particleNode.addParticleSystem(particleSytem)particleNode.position = SCNVector3Make(0, Y, 0)self.scene.rootNode.addChildNode(particleNode)

节点点击事件

      //给 场景视图sceneView 添加点击事件let tap = UITapGestureRecognizer(target: self, action: #selector(tapHandle(gesture:)))sceneView.addGestureRecognizer(tap)
  @objc func tapHandle(gesture:UITapGestureRecognizer){let results:[SCNHitTestResult] = (self.sceneView?.hitTest(gesture.location(ofTouch: 0, in: self.sceneView), options: nil))!guard let firstNode  = results.first else{return}// 这就是点击到的节点 可以对他做一些事情 或者根据这个节点的某些属性执行不同的方法let node = firstNode.node.copy() as! SCNNodeif firstNode.node == self.selectNode {...推远照片...}else{...拉近照片...selectNode = node}}

节点动画

我的另一篇文章中有详细记录ARKit-动画
//拉近(推远)照片

          //这只是其中一种方法let newPosition  = SCNVector3Make(firstNode.node.worldPosition.x*2, firstNode.node.worldPosition.y*2, firstNode.node.worldPosition.z*2)let comeOut = SCNAction.move(to: newPosition, duration: 1.2)firstNode.node.runAction(comeOut)

自传/公转

            //自转let box = SCNBox(width: boxW, height: boxW, length: boxW, chamferRadius: 0)let boxNode = SCNNode(geometry: box)boxNode.position = vector3let emptyNode = SCNNode()emptyNode.position = SCNVector3ZeroemptyNode.rotation = SCNVector4Make(0, 1, 0, Float.pi/Float(L/2) * Float(index))emptyNode.addChildNode(boxNode)photoRingNode.addChildNode(emptyNode)let ringAction = SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: right, z: 0, duration: 2))boxNode.runAction(ringAction)//公转 把节点加到一个正在自传的节点上就可以了

录屏

录屏是使用ReplayKit完成的
开始录屏

    协议      RPScreenRecorderDelegate,RPPreviewViewControllerDelegateRPScreenRecorder.shared().startRecording(handler: nil)RPScreenRecorder.shared().delegate = self

录制代理

func screenRecorder(_ screenRecorder: RPScreenRecorder, didStopRecordingWith previewViewController: RPPreviewViewController?, error: Error?) {print(error ?? "error")if error != nil{print("error:", error ?? "")DispatchQueue.main.async {let string = error?.localizedDescriptionITTPromptView .showMessage(string, andFrameY: 0)print(string ?? "")//录制期间失败self.showFailReplay()}}else{print("else")}print("start recording handler")}//录制失败func showFailReplay(){let sb = UIStoryboard(name: "Main", bundle: nil)let vc = sb.instantiateViewController(withIdentifier: "HKExplainViewController")self.navigationController?.pushViewController(vc, animated: true)self.replayButtonRight.constant = 85;for button in self.smailButtons {button.alpha = 1}self.mainButton.alpha = 1UIView.animate(withDuration: 2.5) {self.stopReplayButton.alpha = 0self.view.layoutIfNeeded()}}

结束并弹出预览控制器

      RPScreenRecorder.shared().stopRecording { (vc, erroe) invc?.previewControllerDelegate = selfvc?.title = "We Are"self.present(vc!, animated: true, completion: nil)}

预览控制器的代理

    func previewController(_ previewController: RPPreviewViewController, didFinishWithActivityTypes activityTypes: Set<String>) {print(activityTypes)//取消if activityTypes.count == 0 {previewController.dismiss(animated: true, completion: nil)}//保存if activityTypes.contains("com.apple.UIKit.activity.SaveToCameraRoll"){ITTPromptView .showMessage("视频已保存在相册", andFrameY: 0)previewController.dismiss(animated: true, completion: nil)//检测到您刚刚保存了视频 是否想要分享let delay = DispatchTime.now() + .seconds(2)DispatchQueue.main.asyncAfter(deadline: delay) {self.outputVideo()}}}

目前所有代码已上传至 github https://github.com/SherlockQi/HeavenMemoirs
欢迎(跪求)Star!

线上项目开源 -- WeAre(AR 相册)相关推荐

  1. iOS宇宙大战游戏、调试工具、各种动画、AR相册、相机图片编辑等源码

    iOS精选源码 日期时间选择器,swift Space Battle 宇宙大战 SpriteKit游戏源码 LLDebugTool - 便捷的IOS调试工具(新增截屏功能) 相机扫描or长按识别二维码 ...

  2. 多款开源免费网络相册/相册系统源码推荐

    Flickr和Picasa是目前互联网两家知名的免费照片储存.分享的网站.当然你也可以拥有一个类似的网站,笔者今天整理并推荐几款国内外开源的相册源码. Gallery Gallery 是国外一个免费开 ...

  3. 用php做一个相册的程序,开源免费PHP相册程序–Piwigo

    开源免费PHP相册程序–Piwigo 安装指南: 最低要求 一个可支持 MySQL 5 和 PHP 5.3 的主机空间 全部要求 一个可支持php的网站服务器 支持 MySQL 5 PHP 5.3 1 ...

  4. 时光印象AR相册使用说明

    时光印象AR相册使用说明 时光印象AR相册可以让你的相册动起来.你可以联系我们,定制AR相册,即可获得一份精美的实体相册以及AR电子相册.实体相册及传统的相册,记录您的美好瞬间.而AR电子相册则不仅包 ...

  5. 微信小程序AR相册开发

    小程序AR相册开发 识别图片在 marker 目录 视频地址保存在云识别的关联信息中,不同识别图播放不同视频 1. 下载官方提供的demo代码 mini-webar: 微信小程序WebAR识别例子 2 ...

  6. Blippar放大招,要开源其AR和计算机视觉技术

    AR公司Blippar将向第三方开发者提供AR和计算机视觉技术API,来推动他们的AR商业应用解决方案的发展. 致力于用AR技术帮助一些大品牌进行品牌故事和消费者营销的AR公司Blippar,最近对外 ...

  7. 基于OpenXR,Collabora推开源VI-SLAM AR/VR定位系统

    XR最关键的难题之一就是定位,为了定位XR头显在现实世界中的位置和角度,厂商们采用了多种方案,比如机械传感器.惯性传感器.磁传感器.声学传感器等等.这些定位方式有一个共同的问题,那就是传感器不够完善, ...

  8. Google开源的AR/VR开发库Lullaby

    Lullaby https://github.com/google/lullaby

  9. Chrome浏览器的用法

    Chrome浏览器的用法 快捷键 Ctrl+N Opens a new window. Ctrl+T Opens a new tab. Press Ctrl+O, then select file. ...

最新文章

  1. Scratch等级考试(二级)模拟题
  2. Laravel中使用模型对数据进行操作
  3. Pandas简明教程:八、Pandas数据透视表
  4. 1.5 训练/开发/测试集划分-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授
  5. 统计学习方法第十九章作业:马尔可夫链蒙特卡罗法、吉布斯抽样算法(书上题目) 代码实现
  6. 支付宝支付—沙箱环境使用
  7. c语言贪吃蛇黑方框,[求助][贪吃蛇]源程序,请教其中一个问题。
  8. ios 音高测试软件,‎App Store 上的“绝对音感训练!”
  9. leetcode 题库46. 把数字翻译成字符串
  10. 近千人点赞!哈佛博士放出超多资源,机器学习课程教程小抄全都有
  11. Nginx安装使用及与tomcat实现负载均衡
  12. 在firefox中backspace返回键不能回到之前的页面
  13. CPython 解释器 与 VC 编译器版本对应关系
  14. python(45)内置函数:os.system() 和 os.popen()
  15. 21点游戏java实现
  16. SQL Server2016安装教程
  17. c语言 printf 输出 long 整型
  18. 关于降低软件开发过程中沟通成本的思考
  19. 完美解决Chrome主页老是被毒霸网址大全篡改
  20. Hardhat以太坊智能合约开发框架基础教程

热门文章

  1. java 查询大批量数据 内存溢出_mybatis查询大量数据内存溢出解决办法
  2. ILRuntime1.安装
  3. java 网页提示被阻止怎么办_win7系统网页提示应用程序被JAVA安全阻止_win7系统网页提示应用程序被JAVA安全阻止解决方法-系统屋...
  4. ubuntu下libmodbus库的使用
  5. java异步执行--
  6. 用c语言编写MIDI程序,使用C语言编写钢琴小程序
  7. 仿抖音滑动小短剧影视微信小程序源码带支付收益等模式
  8. 【linux】Debian10.8安装中文输入法-搜狗输入法
  9. android 系统声音文件对应目录
  10. android 飞入购物车,贝塞尔曲线实现物品飞入购物车效果