UIImagePickerController 和 iCloud 照片

3

切换到iCloud照片后,UIImagePickerController返回的某些图像似乎非常模糊。看起来这些图像是从iCloud照片中获取的。

我能否检索原始图像、过滤掉iCloud照片中的图像,还是必须切换到其他框架以执行UIImagePickerController的功能?


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

3

根据症状,我猜测您正在使用类似于以下方式加载图像:

    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

这将解决问题,但显然不太理想。如果您想继续使用Photos而不实现自己的iCloud解决方案,并保持“优化iPhone存储”设置,则可以使用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图片时遇到的类似问题。参考此帖子


你为什么要使用信息字典中的referenceURL来获取PHAsset,而不是直接访问该字典的phAsset值?请参阅https://developer.apple.com/documentation/uikit/uiimagepickercontroller/infokey/2890963-phasset。 - strnmn
@strnmn 我已经按照你的建议编辑了我的答案。这适用于iOS 11或更高版本。如果您支持旧版iOS,则仍需要旧的referenceURL。我支持的最早版本是iOS9。 - endavid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接