如何在iOS中以编程方式使用PHPickerViewController加载原始图像?

问题描述 投票:0回答:3

我可以加载普通图像:public.image 类型。
Apple proRaw(adobe raw 图像类型:DNG 格式)可用于 iPhone 12 系列。
因此,我使用 RAW 图像进行拍摄,并且想从应用程序加载 DNG 文件。
但我无法使用 PHPicker 加载图像。 通常,如下代码。

PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
configuration.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[[PHPickerFilter imagesFilter], [PHPickerFilter livePhotosFilter]]];

PHPickerViewController *pickerController = [[PHPickerViewController alloc] initWithConfiguration:configuration];
pickerController.delegate = self;
[pickerController setModalPresentationStyle:UIModalPresentationCustom];
[pickerController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[viewController presentViewController:pickerController animated:YES completion:nil];

-(void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14)) {
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    PHPickerResult *result = [results firstObject];
    
    if ([result.itemProvider canLoadObjectOfClass:[UIImage class]]) {       // 1
        [result.itemProvider loadObjectOfClass:[NSObject class] completionHandler:^(__kindof id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {
            if ([object isKindOfClass:[UIImage class]]) {
                UIImage *image = object;
                ...
            }
        }];
    }

在注释1行中,返回NO。
如何使用 PHPicker 加载原始图像?

ios photokit phpickerviewcontroller
3个回答
3
投票

使用

loadFileRepresentation
将照片数据放入
CGImage
对象中,这对我有用。比如:

result.itemProvider.loadFileRepresentation(forTypeIdentifier: "public.image") { url, _ in
    guard let url = url,
          let data = NSData(contentsOf: url),
          let source = CGImageSourceCreateWithData(data, nil),
          let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil) else {
      // handle
    }
    let image = UIImage(cgImage)
    ...
}

[result.itemProvider loadFileRepresentationForTypeIdentifier:@"public.image" completionHandler:^(NSURL * _Nullable url, NSError * _Nullable error) {
    if (url) {
        NSData *data = [NSData dataWithContentsOfURL:url];
        CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
        CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, NULL);
        UIImage *image = [UIImage imageWithCGImage:cgImage];
        ...
    }
}];

您可能需要使用

CGImageSourceCopyPropertiesAtIndex
来获取元数据字典,使用
kCGImagePropertyOrientation
键找到正确的值,将其从
CGImagePropertyOrientation
转换为
UIImage.Orientation
,然后将其传递给
UIImage
初始化程序.

这比仅仅使用

loadObjectOfClass
要复杂一些,但它不需要照片访问授权。


0
投票

我找到了一个解决方案,可以在不损失 RAW 图像质量的情况下完成此操作:

itemProvider.loadFileRepresentation(forTypeIdentifier: "public.image") { url, _ in
    guard let url = url else {
        debugPrint("No RAW Url")
        return
    }
    
    guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil) else {
        debugPrint("Could not create image source from URL")
        return
    }

    let options = [kCGImageSourceShouldCache: false] as CFDictionary
    guard let cgImage = CGImageSourceCreateImageAtIndex(imageSource, 0, options) else {
        debugPrint("Could not create CGImage from source")
        return
    }
    
    let image = UIImage(cgImage: cgImage)
}

-2
投票
  1. 您也可以使用此代码。用于打开新的PHPicker

  2. 有关 WWDC21 中 PHPicker 的更多知识PHPicker WWDC20 视频PHPicker WWDC21 视频

  3. WWDC PHPicker 笔记 PHPicker 笔记


import Photos
import PhotosUI


// MARK: - PHPicker Configurations (PHPickerViewControllerDelegate)
extension ViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
         picker.dismiss(animated: true, completion: .none)
         results.forEach { result in
               result.itemProvider.loadObject(ofClass: UIImage.self) { reading, error in
               guard let image = reading as? UIImage, error == nil else { return }
               DispatchQueue.main.async {
                   self.profilePictureOutlet.image = image
                   // TODO: - Here you get UIImage
               }
               result.itemProvider.loadFileRepresentation(forTypeIdentifier: "public.image") { [weak self] url, _ in
                // TODO: - Here You Get The URL
               }
          }
       }
  }

   /// call this method for `PHPicker`
   func openPHPicker() {
       var phPickerConfig = PHPickerConfiguration(photoLibrary: .shared())
       phPickerConfig.selectionLimit = 1
       phPickerConfig.filter = PHPickerFilter.any(of: [.images, .livePhotos])
       let phPickerVC = PHPickerViewController(configuration: phPickerConfig)
       phPickerVC.delegate = self
       present(phPickerVC, animated: true)
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.