UIImagePickerController and iCloud photos

只愿长相守 提交于 2020-02-25 03:01:10

问题


After switching to iCloud Photo, it seems that some of the images returned by UIImagePickerController are very blur. It looks like the image are taken from iCloud Photo.

Am I able to retrieve the original image, or filter off iCloud Photo images, or do I have to switch to other frameworks to do what UIImagePickerController do?


回答1:


From the symptoms, I'm going to assume you are using something like this to load your images:

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            loadImageInMemory(image)
        }
        picker.dismiss(animated: true, completion: nil)
        self.presentingViewController?.dismiss(animated: true, completion: nil)
    }

where loadImageInMemory is a function where you process the image.

It turns out that if you use that method, images stored over iCloud may be retrieved in lower quality than the original. A way to verify that this is the case is to change your Photos settings. From the Settings app:

Settings -> Photos -> Download and Keep Originals

This would fix the issue, but of course it's not desirable. If you want to keep using Photos, instead of implementing your own iCloud solution, while keeping the Optimize iPhone Storage setting, you can use PhotoKit to retrieve the original image.

Use this code instead:

import Photos

// ...

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // it will be loaded asynchronously
        loadImageFromPicker(info: info)
        picker.dismiss(animated: true, completion: nil)
        self.presentingViewController?.dismiss(animated: true, completion: nil)
    }

    private func loadImageFromPicker(info: [UIImagePickerController.InfoKey : Any]) {
        guard let referenceURL = info[UIImagePickerController.InfoKey.referenceURL] as? URL else {
            return
        }
        let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
        guard let phAsset = fetchResult.firstObject else {
            return
        }
        // size doesn't matter, because resizeMode = .none
        let size = CGSize(width: 32, height: 32)
        let options = PHImageRequestOptions()
        options.version = .original
        options.deliveryMode = .highQualityFormat
        options.resizeMode = .none
        options.isNetworkAccessAllowed = true
        PHImageManager.default().requestImage(for: phAsset, targetSize: size, contentMode: .aspectFit, options: options) { [weak self] (image, info) in
            if let s = self, let image = image {
                s.loadImageInMemory(image)
            }
        }
    }

This code will work with both local images and iCloud images.

This has fixed a similar problem I experienced working with small PNG images with alpha. See this other post for reference.



来源:https://stackoverflow.com/questions/25012731/uiimagepickercontroller-and-icloud-photos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!