【问题标题】:UIImagePickerController and iCloud photosUIImagePickerController 和 iCloud 照片
【发布时间】:2014-09-20 16:08:56
【问题描述】:

切换到iCloud Photo后,UIImagePickerController返回的部分图片好像很模糊。看起来图像是从 iCloud 照片中拍摄的。

我是否能够检索原始图像,或者过滤掉 iCloud 照片图像,或者我是否必须切换到其他框架来执行 UIImagePickerController 的操作?

【问题讨论】:

  • 我认为这与我发布的另一个问题有关:stackoverflow.com/q/60254076/1765629 - 我假设您的照片设置下有“优化 iPhone 存储”?尝试切换到“下载并保留原件”以进行测试。如果它解决了问题,那么我们“只是”需要找到另一种方法来获取原件,如果可能的话...... ????

标签: ios swift uiimagepickercontroller icloud


【解决方案1】:

从症状来看,我假设您正在使用类似的东西来加载您的图像:

    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)
    }

其中loadImageInMemory 是处理图像的函数。

事实证明,如果您使用该方法,存储在 iCloud 上的图像可能会以低于原始质量的质量被检索。验证这种情况的一种方法是更改​​您的照片设置。在“设置”应用中:

Settings -> Photos -> Download and Keep Originals

这可以解决问题,但当然是不可取的。如果您想继续使用照片,而不是实现自己的 iCloud 解决方案,同时保持Optimize iPhone Storage 设置,您可以使用PhotoKit 检索原始图像。

改用此代码:

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]) {
        var phAsset: PHAsset?
        if #available(iOS 11.0, *) {
            phAsset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset
        } else {
            // Fallback on earlier versions
            if let referenceURL = info[UIImagePickerController.InfoKey.referenceURL] as? URL {
                let fetchResult = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
                phAsset = fetchResult.firstObject
            }
        }
        guard let asset = phAsset 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: asset, targetSize: size, contentMode: .aspectFit, options: options) { [weak self] (image, info) in
            if let s = self, let image = image {
                s.loadImageInMemory(image)
            }
        }
    }

此代码适用于本地图像和 iCloud 图像。

这解决了我在处理带有 alpha 的小型 PNG 图像时遇到的类似问题。参考this other post

【讨论】:

  • 您是否有理由使用信息字典中的referenceURL 来获取PHAsset,而不是直接访问该字典的phAsset 值?见developer.apple.com/documentation/uikit/uiimagepickercontroller/…
  • @strnmn 我已经根据您的建议编辑了我的答案。这适用于 iOS 11 或更高版本。如果您支持旧版本的 iOS,您仍然需要旧的 referenceURL。我支持的最早版本是iOS9。
猜你喜欢
  • 2013-06-11
  • 2020-09-07
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多