Как добавить UIImage к сцене в AR Kit - PullRequest
0 голосов
/ 16 мая 2018

У меня есть сеанс AR, который добавляет SCNText и 3D-объекты. А теперь я хочу добавить UIImage из Image Picker и не знаю, как это сделать. Есть ли решения?

РЕШЕНИЕ

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)

1 Ответ

0 голосов
/ 16 мая 2018

Как я уверен, вы знаете, что SCNGeometry имеет свойство materials, которое просто:

Контейнер для цвета или текстуры одного из визуальных материалов. свойства.

Таким образом, вы можете визуализировать UIImage на SCNGeometry, используя, например, свойство diffuse.

Вот полностью рабочий и проверенный пример. Который загружает UIImagePickerController через 5 секунд, а затем создает SCNNode с SCNPlane Geometry, содержимое которого установлено на 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>

Этого должно быть более чем достаточно, чтобы вы начали ...

...