Search code examples
iosswiftswift4arkitios12

How to load ARReferenceImage from document directory?


Currently, I am using below code to load ARReferenceImage from "AR Resources" of Assets.xcassets,

guard let trackingImages =  ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
    print("Missing expected asset catalog resources.")
    return
}
configuration.trackingImages = trackingImages

Now, I am downloading images from the server to the custom folder called "Images" in the document directory of the iOS app.

How can I use those images as "tracking images"?


Solution

  • In order to load custom ARReference images from a specified location other than the default ARAssets Folder you need to create them using the following method:

    init(CGImage, orientation: CGImagePropertyOrientation, physicalWidth: CGFloat)
    

    In this example I am using ARWorldTrackingConfiguration but the principle if using ARImageTrackingConfiguration is the same.

    Lets say that you store all your downloaded images into an array of [UIImage] e.g:

    let imagesFromServer: [UIImage] = [UIImage(named: "gitHubIcon")!, UIImage(named: "stackOverflowIcon")!]
    

    You can then turn these into ARReferenceImages using something like this:

    /// Converts An Array Of [UIImage] Into A Set Of ARReferenceImages
    ///
    /// - Parameter images: [UIImage])
    /// - Returns: Set<ARReferenceImage>
    func loadedImagesFromDirectoryContents(_ images: [UIImage]) -> Set<ARReferenceImage>{
    
        var index = 0
        var customReferenceSet = Set<ARReferenceImage>()
    
        images.forEach { (downloadedImage) in
    
            //1. Convert The UIImage To A CGImage
            guard let cgImage = downloadedImage.cgImage else { return }
    
            //2. Get The Width Of The Image
            let imageWidth = CGFloat(cgImage.width)
    
            //3. Create A Custom AR Reference Image With A Unique Name
            let customARReferenceImage = ARReferenceImage(cgImage, orientation: CGImagePropertyOrientation.up, physicalWidth: imageWidth)
            customARReferenceImage.name = "MyCustomARImage\(index)"
    
            //4. Insert The Reference Image Into Our Set
            customReferenceSet.insert(customARReferenceImage)
    
            print("ARReference Image == \(customARReferenceImage)")
    
            index += 1
    
    
        }
    
    
        //5. Return The Set
        return customReferenceSet
    
    }
    

    Remembering that ARWorldTrackingConfiguration takes a Set<ARReferenceImage>.

    You can then initialise your custom configurations detectionImages like so:

     let detectionImages = loadedImagesFromDirectoryContents(imagesFromServer)
    
     configuration.detectionImages = detectionImages
    
     augmentedRealitySession.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    

    Hope it points you in the right direction...