Показать изображение на SCNPlane в наборе Scene и наборе AR в быстром iOS - PullRequest
0 голосов
/ 20 февраля 2020

Я следовал этому руководству raywenderlich, чтобы обнаружить изображение, используя AR и Scene Kit. В этом примере они показали отображение видео поверх обнаруженного изображения.

https://www.raywenderlich.com/6957-building-a-museum-app-with-arkit-2

Я хочу отобразить изображение поверх обнаруженного изображения. Пожалуйста, помогите мне, как я могу добавить childNode в SCNNode, чтобы я мог отобразить изображение поверх него.

Вот код, который я попробовал, он не работает, показывая пустой белый экран.

                            DispatchQueue.main.async {

                        let size = imageAnchor.referenceImage.physicalSize

                        let imageView = UIImageView(image: UIImage(named: "BG.png")!)

                        let imgMaterial = SCNMaterial()
                        imgMaterial.diffuse.contents = imageView

                        let imgPlane = SCNPlane(width: size.width, height: size.height)
                        imgPlane.materials = [imgMaterial]

                        let imgNode = SCNNode(geometry: imgPlane)
                        imgNode.eulerAngles.x = -.pi / 2


                        node.addChildNode(imgNode)
                         node.opacity = 1

                        }

Помогите, пожалуйста, показать изображение поверх обнаруженного изображения. Заранее спасибо.

Я могу показать изображение поверх обнаруженного изображения, но ему требуется много памяти, что не так в этом коде.

И так же, как при просмотре изображения, которое я отображаю Воспроизведение GIF поверх обнаруженного изображения с кодом ниже.

                                let size = imageAnchor.referenceImage.physicalSize

                            let imgNameFromDoc = person["actionToTake"] as! String

                            let documentsPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first

                            let imgpath = documentsPathURL?.appendingPathComponent("/Packages/\(self.selectedDatasetName)/3DScenes/\(imgNameFromDoc)")

                            let imageData = try! Data(contentsOf: URL(fileURLWithPath: imgpath!.path))


                            let imageURL = UIImage.gifImageWithData(imageData)


                            self.gifImgView = UIImageView(image: imageURL)

                            let imgMaterial = SCNMaterial()
                            imgMaterial.diffuse.contents = self.gifImgView

                            let imgPlane = SCNPlane(width: CGFloat(scaleActionSize(wid: Float(size.width), hei:Float(size.height))[0]), height: CGFloat(scaleActionSize(wid: Float(size.width), hei:Float(size.height))[1]))

                            imgPlane.materials = [imgMaterial]

                            let imgNode = SCNNode(geometry: imgPlane)
                            imgNode.eulerAngles.x = -.pi / 2


                            node.addChildNode(imgNode)
                            node.opacity = 1

С помощью расширения изображения я показываю GIF при просмотре изображения поверх обнаруженного изображения. https://github.com/kiritmodi2702/GIF-Swift/blob/master/GIF-Swift/iOSDevCenters%2BGIF.swift

Как загрузить изображение GIF в Swift?

Я перетащил класс iOSDevCenters + GIF.swift в приложение и отобразил gif.

Когда я использую это представление изображений gif для отображения изображений gif и изображений для отображения изображений, в Xcode, работающем с iPad, требуется более 800 МБ памяти.

Может кто-нибудь помочь мне найти утечки памяти (пробовал с инструментами, которые не могут исправить) или что-то не так в этом коде.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

Отображение представлений UIKit как содержимого свойства материала не поддерживается. Вместо UIImageView вы должны напрямую использовать UIImage или, что еще лучше, просто String или URL, который указывает на изображение на диске. Таким образом, изображение не будет загружено дважды в память (в SceneKit и UIKit).

0 голосов
/ 20 февраля 2020

Полагаю, у вас работает отслеживание изображений.

Следующий метод вызывается при добавлении новой привязки. В этом случае, когда ваше изображение отслеживается. Таким образом, узлом параметра является отслеживаемое изображение, и вы можете добавить дочерний элемент к этому изображению, как в учебнике. Таким образом, вы можете попробовать следующее (используйте ARSCNViewDelegate):

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    DispatchQueue.main.async {
        let imageView = UIImageView(image: UIImage())

        let imgMaterial = SCNMaterial()
        imgMaterial.diffuse.contents = imageView

        let imgPlane = SCNPlane(width: 0.1, height: 0.1)
        imgPlane.materials = [imgMaterial]

        let imgNode = SCNNode(geometry: imgPlane)
        imgNode.eulerAngles.x = -.pi / 2


        node.addChildNode(imgNode)
        node.opacity = 1

    }

}

imgNode добавляется к узлу, а узел уже добавляется к сцене. Так что же произойдет, если узел не будет добавлен в сцену? Вы должны добавить его самостоятельно. Так что, если вы не используете метод рендерера, примером этого является следующий:

self.imgNode?.position = SCNVector3(0, 0, 0)
sceneView.scene.rootNode.addChildNode(self.imgNode)
...