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

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

我正在使用 Xcode 11.4 和 Swift 5。

【问题讨论】:

    标签: swift uiimagepickercontroller phasset


    【解决方案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】:

      有两种方法:

      1. 您可以使用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)
        }
        

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

      2. 您可以从 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 框架。

      【讨论】:

        猜你喜欢
        • 2018-04-25
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多