radar
radar

Reputation: 510

Swift 3 load image from local directory

I'm new to iOS dev and cannot figure out how to load an image in an imageView from a local directory. I use imagePickerController to pick an image, get its info, then use this information to display the image in the imageView.

Here is the code to pick the image and its info dictionary:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let image             = info[UIImagePickerControllerOriginalImage] as! UIImage

        let imageUrl          = info[UIImagePickerControllerReferenceURL] as! NSURL
        let imageName         = imageUrl.lastPathComponent
        let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let photoURL          = NSURL(fileURLWithPath: documentDirectory)
        let localPath         = photoURL.appendingPathComponent(imageName!)!

        imagesList.append(localPath)

        picker.dismiss(animated: true, completion: nil)
    }

Then, and here is where I'm looking for some help, I want to use either localPath or imageUrl to load the image in another imageView but cannot figure out how. I tried

func changeImage(_ sender: Any) {
        if imagesList.count > 0 {
            let imageUrlPath = imagesList[indexList]
            let urlString: String = imageUrlPath.absoluteString

            imageView.image = UIImage(contentsOfFile: urlString)

            indexList = (indexList + 1) % imagesList.count
        }
    }

But I cannot have something working. Any idea how I can achieve that?

Thank you for your help.

Upvotes: 1

Views: 3161

Answers (1)

DonMag
DonMag

Reputation: 77700

You'll want to save a reference to PHAsset objects, not URL strings.

Start with defining your Array as:

var imagesList = [PHAsset]()

Then, in didFinishPickingMediaWithInfo:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    dismiss(animated: true)

    // get the selected image as a UIImage object
    let image = info[UIImagePickerControllerOriginalImage] as! UIImage
    imageView.image = image

    // save a PHAsset reference in imagesList array for later use
    if let imageUrl = info[UIImagePickerControllerReferenceURL] as? URL{

        let assets = PHAsset.fetchAssets(withALAssetURLs: [imageUrl], options: nil)

        if let p = assets.firstObject {

            imagesList.append(p)

        }

    }

}

Next, add a couple "convenience" functions:

func getAssetFullsize(asset: PHAsset) -> UIImage {
    let manager = PHImageManager.default()
    let option = PHImageRequestOptions()
    var img = UIImage()
    option.isSynchronous = true
    let w = asset.pixelWidth
    let h = asset.pixelHeight
    manager.requestImage(for: asset, targetSize: CGSize(width: w, height: h), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
        img = result!
    })
    return img
}

func getAssetThumbnail(asset: PHAsset) -> UIImage {
    let manager = PHImageManager.default()
    let option = PHImageRequestOptions()
    var thumbnail = UIImage()
    option.isSynchronous = true
    let w = 100
    let h = 100
    manager.requestImage(for: asset, targetSize: CGSize(width: w, height: h), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in
        thumbnail = result!
    })
    return thumbnail
}

and finally, when you want to get the actual image:

func changeImage(_ sender: Any) {
    if imagesList.count > 0 {

        // get the full-size image from PHAsset
        imageView.image = getAssetFullsize(asset: imagesList[indexList])

        // or, just get a thumbnail-sized image
        //imageView.image = getAssetThumbnail(asset: imagesList[indexList])

        indexList = (indexList + 1) % imagesList.count

    }
}

Naturally, you'll want to add appropriate error-checking, your own sizing, naming, tracking, etc... but I think this is the direction you want to head.

Upvotes: 2

Related Questions