ARKit 添加来自 url 的参考图像
ARKit add reference images from url
我想从服务器添加 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 警报干净地关闭
一些想法?
问题是您在异步网络请求实际获取图像之前设置了 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!)
}
}
您也不应该在 Swift 中使用 NSArray
,尤其是不应该将具有已知属性的类型转换为 AnyObject
只是为了使用 [=17= 动态检索它们的属性] 与静态键。只需将 Array
与具体类型一起使用,并使用点语法访问属性。
也不需要从 UIImage
到 CIImage
再到 CGImage
的自定义转换,UIImage
有一个内置的 属性,cgImage
可以用于转换。
我想从服务器添加 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 警报干净地关闭
一些想法?
问题是您在异步网络请求实际获取图像之前设置了 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!)
}
}
您也不应该在 Swift 中使用 NSArray
,尤其是不应该将具有已知属性的类型转换为 AnyObject
只是为了使用 [=17= 动态检索它们的属性] 与静态键。只需将 Array
与具体类型一起使用,并使用点语法访问属性。
也不需要从 UIImage
到 CIImage
再到 CGImage
的自定义转换,UIImage
有一个内置的 属性,cgImage
可以用于转换。