问题
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