如何从 UIImagePickerController 获取图像文件名

Posted

技术标签:

【中文标题】如何从 UIImagePickerController 获取图像文件名【英文标题】:How do I get image file name from UIImagePickerController 【发布时间】:2020-06-17 16:02:02 【问题描述】:

我正在尝试从UIImagePickerController 提供的PHAsset 参考中获取文件名,从库中选择并用相机拍照时如何检索图像文件名?

我正在使用 Xcode 11.4 和 Swift 5。

【问题讨论】:

【参考方案1】:

鉴于您已经拥有 PHAsset 对象,PHAssetResource 是您检索文件名所需要的。

let assetResources = PHAssetResource.assetResources(for: asset)

这将为您返回一组PHAssetResource 实例,其中一个是当前图像。

在调试器上检查 PHAssetResource 实例,您可以看到它包含多个文件。这可能包括由 .plist 表示的调整数据以及一张或多张照片。

要获取当前可访问的文件,您需要查找的是密钥isCurrent。 Apple 没有将此键作为 PHAssetResource 的变量公开,但是,他们没有采取任何努力隐藏该值。我假设,查询这个值不会导致应用被拒绝。

您可以直接查询该值,也可以通过扩展 PHAssetResource 来更简洁地查询。

extension PHAssetResource 
    var isCurrent: Bool? 
        self.value(forKey: "isCurrent") as? Bool
    

现在,您可以向[PHAssetResource] 询问isCurrent 的第一个项目以及照片或视频。

let resourceTypes: [PHAssetResourceType] = [.photo, .video, .audio, .fullSizePhoto]
let currentAssetResource = assetResources.first(
   where:  $0.isCurrent == true && resourceTypes.contains($0.type)
)

最后是文件名。

let fileName = currentAssetResource?.originalFilename

注意

PhotoKit 期望开发人员使用抽象资产资源,而不是处理底层文件或数据。似乎允许使用isCurrent。但是,可以通过 ios 更新更改或删除该值。仅当您有提取文件名的强大用例时才这样做。

【讨论】:

【参考方案2】:

有两种方法:

    您可以使用info[.imageURL] 检索UIImagePickerController 为您创建的临时文件的URL。如果您只需要例如资产的扩展,这就足够了。

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) 
    
        // url of temporary file provided by image picker
    
        if let url = info[.imageURL] as? URL 
            print("temp URL", url)                         // file:///private/var/mobile/Containers/Data/Application/.../tmp/FAC0D82B-85A9-4C7A-B69C-58BB53F74CDC.jpeg
        
    
        dismiss(animated: true)
    
    

    但文件名本身与原始资产无关。

    您可以从 Photos 框架中检索原始资产 URL。我们以前可以使用PHImageManager,调用requestImageDataForAsset,然后在生成的信息字典中使用"PHImageFileURLKey",但现在不行了。

    但作为suggested elsewhere,您可以asset.requestContentEditingInput,其中包括资产的URL:

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) 
    
        // url of the original asset
    
        if let asset = info[.phAsset] as? PHAsset 
            asset.requestContentEditingInput(with: nil)  input, info in
                if let fileURL = input?.fullSizeImageURL 
                    print("original URL", fileURL)         // file:///var/mobile/Media/DCIM/100APPLE/IMG_0135.HEIC
                
            
        
    
        dismiss(animated: true)
    
    

    如果你这样做,你显然需要请求照片库的权限,特别是:

    if phphotoLibrary.authorizationStatus() == .notDetermined 
        PHPhotoLibrary.requestAuthorization  granted in
            print(granted)
        
    
    

    您需要在您的Info.plist 中提供一个NSPhotoLibraryUsageDescription 用法字符串。

    就个人而言,当您真的不需要编辑时请求内容编辑输入感觉是错误的,但是 AFAIK,这是目前获得原始资产名称的唯一方法。 (一定有更好的方法:如果您在调试器中浏览 PHAsset,资产名称实际上是埋在那里,但没有暴露出来......也许他们这样做是为了避免与 HEIC 扩展名混淆。)

归根结底,这取决于您需要的名称。如果您只需要临时文件的路径,请使用.imageURL。如果您需要有关原始资产的信息,请使用 .phAsset 和 Photos/PhotoKit 框架。

【讨论】:

以上是关于如何从 UIImagePickerController 获取图像文件名的主要内容,如果未能解决你的问题,请参考以下文章

如何调整自定义 UIButton 的图像大小?

iPhone - 以编程方式删除状态栏

imageWithData图像尺寸变大了?

Segue 图像到另一个视图控制器的问题

imagePickerController 选择照片时出错

如何从其他面板从 JTextField 获取输入