ARKit之路-AR截屏

版权声明:Davidwang原创文章,严禁用于任何商业途径,授权后方可转载。

  截屏是移动手机用户经常使用的一项功能,也是一项特别方便用户保存、分享屏幕信息的方式。移动设备(包括iOS设备和Android设备)都具备方便高效的截屏快捷键。

  但在AR应用中,使用者可能有不同于直接截屏的需求,如剔除屏幕上的UI元素,只保留摄像头图像和渲染的虚拟物体图像;开发人员有时也需要直接获取AR摄像头中的数据进行后续处理,即获取纯粹的不包括UI元素与虚拟物体的摄像头硬件采集的视频图像原始数据,如使用自定义计算机视觉算法。

  截取AR中不包含UI元素的图像并保存到相册中是虚实拍照的一种广泛应用需求,下面我们以这个需求为例,采用两种方法实现;另外,获取设备摄像头采集的图像数据也是开发人员经常使用的功能。为方便读者学习,我们将这3种方法实现代码一并放置在如下代码清单中。

extension ARView :ARSessionDelegate{
    func createPlane(){
        let planeAnchor = AnchorEntity(plane:.horizontal)
        do {
            let cubeMesh = MeshResource.generateBox(size: 0.2)
            var cubeMaterial = SimpleMaterial(color:.white,isMetallic: false)
            cubeMaterial.baseColor = try .texture(.load(named: "Box_Texture.jpg"))
            let cubeEntity = ModelEntity(mesh:cubeMesh,materials:[cubeMaterial])
            cubeEntity.generateCollisionShapes(recursive: false)
            planeAnchor.addChild(cubeEntity)
            self.scene.addAnchor(planeAnchor)
            self.installGestures(.all,for:cubeEntity)
        } catch {
            print("找不到文件")
        }
    }
    
    func snapShotAR(){
        //方法一
         arView.snapshot(saveToHDR: false){(image) in
             UIImageWriteToSavedPhotosAlbum(image!, self, #selector(self.imageSaveHandler(image:didFinishSavingWithError:contextInfo:)), nil)
         }
        //方法二
        /*
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0)
        self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        let uiImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        UIImageWriteToSavedPhotosAlbum(uiImage!, self, #selector(imageSaveHandler(image:didFinishSavingWithError:contextInfo:)), nil)
        */
    }

    func snapShotCamera(){
        guard let pixelBuffer = arView.session.currentFrame?.capturedImage else {
            return
        }
        let ciImage = CIImage(cvPixelBuffer: pixelBuffer),
        context = CIContext(options: nil),
        cgImage = context.createCGImage(ciImage, from: ciImage.extent),
        uiImage = UIImage(cgImage: cgImage!, scale: 1, orientation: .right)
        UIImageWriteToSavedPhotosAlbum(uiImage, self, #selector(imageSaveHandler(image:didFinishSavingWithError:contextInfo:)), nil)
    }
    
    @objc func imageSaveHandler(image:UIImage,didFinishSavingWithError error:NSError?,contextInfo:AnyObject) {
        if error != nil {
            print("保存图片出错")
        } else {
            print("保存图片成功")
        }
    }
}

  在虚实拍照方法(snapShotAR())中,方法一是利用RealityKit中ARView提供的snapshot()方法截取AR场景,使用该方法非常简洁;方法二是将AR场景渲染到离线的缓冲区再转换成图像,这种方法有更好的灵活性,并且可以实现多图像的任意拼接或者截取指定区域的图像。

  在采集硬件摄像头原始图像方法(snapShotCamera())中,是通过ARFrame直接获取来自设备摄像头的图像数据。

  从ARView中获取的图像数据包含场景中的虚拟物体,尺寸大小与设备屏幕显示分辨率一致,而从ARFrame中获取的图像数据为摄像头硬件采集的原始图像信息,尺寸大小与硬件摄像头分辨率相关,与屏幕显示分辨率无关。

  AR截图与采集硬件摄像头图像的效果如下图所示。

在这里插入图片描述

提示
将拍摄的照片保存进相册需要开启“添加照片到相册”权限,开打Info.plist文件,添加以下权限并填写使用描述Privacy - Photo Library Additions Usage Description。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_DavidWang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值