ARKit добавить эталонные изображения из URL - PullRequest
0 голосов
/ 01 октября 2018

Я хочу добавить ARReferenceImages с сервера.Для этого я получаю массив с URL-адресами изображений.T попытался с помощью следующей функции, которая перебирает URL и добавляет новые созданные ARImages в набор.Но это не работает.

    func addReferences(media: NSArray){
    var customReferenceSet = Set<ARReferenceImage>()
    for medium in media{
        let type = (medium as AnyObject).value(forKey: "type");
        let t = type as! String

        let reference = (medium as AnyObject).value(forKey: "reference");
        let ref = reference as! String


        let ide = (medium as AnyObject).value(forKey: "id");
        let id = ide as! String


        let url = URL(string: ref)
        let session = URLSession(configuration: .default)


        let downloadPicTask = session.dataTask(with: url!) { (data, response, error) in

            if let e = error {
                print("Error downloading picture: \(e)")
            } else {

                if let res = response as? HTTPURLResponse {
                    print("Downloaded picture with response code \(res.statusCode)")
                    if let imageData = data {
                        let image = UIImage(data: imageData)!
                        let imageToCIImage = CIImage(image: image)
                        let cgImage = self.convertCIImageToCGImage(inputImage: imageToCIImage!)
                        let arImage = ARReferenceImage(cgImage!, orientation: CGImagePropertyOrientation.up, physicalWidth: 0.2)
                        arImage.name = id
                        customReferenceSet.insert(arImage)
                    } else {
                        print("Couldn't get image: Image is nil")
                    }
                } else {
                    print("Couldn't get response code for some reason")
                }
            }
        }

        downloadPicTask.resume()
    }

    self.configuration = ARWorldTrackingConfiguration()
    self.configuration?.detectionImages = customReferenceSet
    sceneView.session.run(configuration!)
}

Иногда, но не каждый раз, я получаю следующий вывод:

[boringssl_session_read] SSL_ERROR_ZERO_RETURN (6): операция не удалась, потому что соединение было чисто отключенос предупреждением close_notify

Некоторые идеи?

1 Ответ

0 голосов
/ 01 октября 2018

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

.установите detectionImages после того, как все изображения были получены с сервера, чего вы можете достичь, используя DispatchGroup.

func addReferences(media: NSArray){
    var customReferenceSet = Set<ARReferenceImage>()
    let imageFetchingGroup = DispatchGroup()
    for medium in media { 
        let type = (medium as AnyObject).value(forKey: "type");
        let t = type as! String

        let reference = (medium as AnyObject).value(forKey: "reference");
        let ref = reference as! String

        let ide = (medium as AnyObject).value(forKey: "id");
        let id = ide as! String

        let url = URL(string: ref)
        let session = URLSession(configuration: .default)

        imageFetchingGroup.enter()
        let downloadPicTask = session.dataTask(with: url!) { (data, response, error) in
            if let e = error {
                print("Error downloading picture: \(e)")
                imageFetchingGroup.leave()
            } else {
                if let res = response as? HTTPURLResponse {
                    print("Downloaded picture with response code \(res.statusCode)")
                    if let imageData = data {
                        let image = UIImage(data: imageData)!
                        let arImage = ARReferenceImage(image.cgImage!, orientation: CGImagePropertyOrientation.up, physicalWidth: 0.2)
                        arImage.name = id
                        customReferenceSet.insert(arImage)
                        imageFetchingGroup.leave()
                    } else {
                        print("Couldn't get image: Image is nil")
                        imageFetchingGroup.leave()
                    }
                } else {
                    print("Couldn't get response code for some reason")
                    imageFetchingGroup.leave()
                }
            }
        }

        downloadPicTask.resume()
    }

    self.configuration = ARWorldTrackingConfiguration()
    imageFetchingGroup.notify(queue: .main) {
        self.configuration?.detectionImages = customReferenceSet
        sceneView.session.run(configuration!)
    }
}

Вы также не должны использовать NSArray в Swift и особенно не должны приводитьтипы с известными свойствами AnyObject просто для динамического извлечения своих свойств, используя value(forKey:) со статическими ключами.Просто используйте Array с конкретным типом и получите доступ к свойствам с помощью точечного синтаксиса.

Также нет необходимости настраивать преобразование из UIImage в CIImage, а затем в CGImage, UIImageимеет встроенное свойство cgImage, которое можно использовать для преобразования.

...