【问题标题】:How to add UIImage to a Scene in AR Kit如何在 AR Kit 中将 UIImage 添加到场景中
【发布时间】:2018-05-16 13:21:24
【问题描述】:

我有 AR 会话,它也添加了 SCNText 和 3D 对象。现在,我想从 Image Picker 添加 UIImage 并且不知道该怎么做。有什么解决办法吗?

解决方案

func insertImage(image: UIImage, width: CGFloat = 0.3, height: CGFloat = 0.3) -> SCNNode {
    let plane = SCNPlane(width: width, height: height)
    plane.firstMaterial!.diffuse.contents = image
    let node = SCNNode(geometry: plane)
    node.constraints = [SCNBillboardConstraint()]
    return node
}

let image = insertImage(image: addedImage)
node.addChildNode(image)

【问题讨论】:

    标签: ios swift arkit


    【解决方案1】:

    我相信你知道SCNGeometry 有一个materials 属性,它很简单:

    一种材料的视觉颜色或纹理的容器 属性。

    因此,您可以使用例如diffuse 属性将UIImage 渲染到SCNGeometry

    这是一个完全有效且经过测试的示例。它在 5 秒后加载 UIImagePickerController,然后创建一个带有 SCNPlane GeometrySCNNode,其内容设置为选定的 UIImage

    代码已完全注释,因此应该很容易理解:

    //-------------------------------------
    //MARK: UIImagePickerControllerDelegate
    //-------------------------------------
    
    extension ViewController: UIImagePickerControllerDelegate{
    
        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    
            //1. Check We Have A Valid Image
            if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
    
                //2. We Havent Created Our PlaneNode So Create It
                if planeNode == nil{
    
                    //d. Dismiss The Picker
                    picker.dismiss(animated: true) {
    
                        //a. Create An SCNPlane Geometry
                        let planeGeometry = SCNPlane(width: 0.5, height: 0.5)
    
                        //b. Set's It's Contents To The Picked Image
                        planeGeometry.firstMaterial?.diffuse.contents = self.correctlyOrientated(selectedImage)
    
                        //c. Set The Geometry & Add It To The Scene
                        self.planeNode = SCNNode()
                        self.planeNode?.geometry = planeGeometry
                        self.augmentedRealityView.scene.rootNode.addChildNode(self.planeNode!)
                        self.planeNode?.position = SCNVector3(0, 0, -1.5)
    
                    }
                }
    
            }
    
             picker.dismiss(animated: true, completion: nil)
        }
    
        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { picker.dismiss(animated: true, completion: nil) }
    
    }
    
    class ViewController: UIViewController, UINavigationControllerDelegate {
    
        //1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
        @IBOutlet weak var augmentedRealityView: ARSCNView!
    
        //2. Create Our ARWorld Tracking Configuration & Session
        let configuration = ARWorldTrackingConfiguration()
        let augmentedRealitySession = ARSession()
    
        //3. Create A Reference To Our PlaneNode
        var planeNode: SCNNode?
        var planeGeomeryImage: UIImage?
    
        //---------------
        //MARK: LifeCycle
        //---------------
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            //1. Setup The Session
            setupARSession()
    
            //2. Show The UIImagePicker After 4 Seconds
            DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
                self.selectPhotoFromGallery()
            }
    
        }
    
        override func didReceiveMemoryWarning()  { super.didReceiveMemoryWarning() }
    
        //-------------
        //MARK: ARSetup
        //-------------
    
        func setupARSession(){
    
            //1. Run Our Session
            augmentedRealityView.session = augmentedRealitySession
            augmentedRealitySession.run(configuration, options: [.resetTracking, .removeExistingAnchors])
        }
    
        //---------------------
        //MARK: Image Selection
        //---------------------
    
        /// Loads The UIImagePicker & Allows Us To Select An Image
        func  selectPhotoFromGallery(){
    
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary){
                let imagePicker = UIImagePickerController()
                imagePicker.delegate = self
                imagePicker.allowsEditing = true
                imagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
                self.present(imagePicker, animated: true, completion: nil)
            }
    
        }
    
    
        /// Correctly Orientates A UIImage
        ///
        /// - Parameter image: UIImage
        /// - Returns: UIImage?
        func correctlyOrientated(_ image: UIImage) -> UIImage {
            if (image.imageOrientation == .up) { return image }
    
            UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
            let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
            image.draw(in: rect)
    
            let normalizedImage = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
    
            return normalizedImage
        }
    
    }
    

    不要忘记将NSPhotoLibraryUsageDescription 添加到您的info.plist

    <key>NSPhotoLibraryUsageDescription</key>
    <string>For ARkit</string>
    

    这应该足以让你开始......

    【讨论】:

    • 感谢您的回复,但我已经完成了选择器的所有工作,问题是像 2D 对象一样发布它。看看我帖子中的SOLUTION编辑。
    猜你喜欢
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 2015-10-08
    相关资源
    最近更新 更多