运行时将UIImage保存至ARKit的AR Resource Group的实现疑问
无法直接写入AR Resource Group?这是原因和替代方案
首先得明确一个核心事实:你提到的AR Resources组本质是编译时嵌入App Bundle的资源目录,而iOS的App Bundle在运行时是只读的——这就是为什么找不到写入方法的关键原因,苹果根本没有提供往这个目录写入文件的接口。
那要实现「运行时添加图片用于后续AR图像检测」,得换个思路:把自定义图片存在App沙箱的可读写目录里,手动创建ARReferenceImage对象来使用。具体步骤如下:
步骤1:保存快照到沙箱可读写目录
先把你截取的snapshot保存到App的Documents目录(这是沙箱里默认的可读写目录),代码示例:
guard let snapshot = self.viewController?.sceneView.snapshot() else { print("Failed to take snapshot") return } // 获取Documents目录路径 guard let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } let imageURL = docsDir.appendingPathComponent("customARImage.png") // 保存图片(可根据需求转成JPG并调整质量) if let imageData = snapshot.pngData() { do { try imageData.write(to: imageURL) print("Snapshot saved to: \(imageURL.path)") } catch { print("Failed to save image: \(error.localizedDescription)") } }
步骤2:从沙箱加载图片并创建ARReferenceImage
后续需要用这张图做检测时,直接从沙箱读取图片,转换成ARReferenceImage并加入AR配置:
// 获取Documents目录路径 guard let docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } let imageURL = docsDir.appendingPathComponent("customARImage.png") // 加载图片并创建ARReferenceImage if let imageData = try? Data(contentsOf: imageURL), let cgImage = UIImage(data: imageData)?.cgImage { // 必须设置物理尺寸(单位是米,尽量匹配实际物体的真实宽度,否则检测精度会受影响) let referenceImage = ARReferenceImage(cgImage, orientation: .up, physicalWidth: 0.2) // 给图片设置名字,方便后续识别时区分来源 referenceImage.name = "CustomSnapshot" // 更新ARSession的配置 guard let configuration = self.viewController?.sceneView.session.configuration as? ARImageTrackingConfiguration else { return } // 可以把自定义图片和原AR Resources里的图片合并使用 let existingImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) ?? [] configuration.trackingImages = existingImages.union([referenceImage]) // 重启session应用新配置 self.viewController?.sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) }
额外注意点
- 物理尺寸的设置很关键:
physicalWidth参数要尽量贴合实际物体的真实宽度,否则AR检测的准确性会大打折扣。 - 如果需要保存多张自定义图片,可以在Documents目录下创建子文件夹管理,避免文件名冲突。
- 沙箱里的文件会持久保存,直到用户卸载App或手动清理存储,下次启动App时可以直接加载使用这些自定义参考图。
内容的提问来源于stack exchange,提问作者michael-martinez
相关产品推荐
相关产品推荐

