【问题标题】:UIImage to PHAssetUIImage 到 PHAsset
【发布时间】:2016-08-30 20:21:06
【问题描述】:

我正在尝试将UIImage 转换为PHAsset,但找不到任何解决方案。我发现反之亦然(即PHAssetUIImage)。

场景是,我正在将自定义目录中的图像提取到PHAssetCollection 并显示在UICollectionView 中。我还想在此处包含来自上一个屏幕的更多图像,这些图像来自远程源。我不想将远程图像保存到我的目录中,但想将它们包含在我的 UICollectionView 中。

请建议我解决方案或一些好的替代方案,以便UICollectionView 的来源相同(即PHAssetCollection

【问题讨论】:

  • 找到任何解决方案了吗?我也面临同样的问题

标签: ios swift uiimage photosframework


【解决方案1】:

您不想将PHAsset 转换为UIImage。我不知道这是否可能;不应该,因为PHAssetUIImage 具有不同的属性、行为等。反之亦然,因为UIImage 的所有属性都可以从PHAsset 派生,反之则不行。

改为将集合视图的数据源更改为[UIImage],同时将PHAsset 转换为UIImage。这种方法很干净,解决了您必须将UIImage 转换为PHImage 的其他问题。

【讨论】:

  • 我不同意——我有一个类似的情况,在呈现附件数据数组时,我会在UICollectionView 中呈现一组缩略图图标。从摄像头获取附件数据时,返回为UIImage。但是,其他类型的附件可能是文件,由URL 引用。然后,此 url 用于确定附件在 didSelect(at index) 方法上的显示方式。所以翻译成PHAsset的目的,就是获取assets-library方案中的URL。
  • 我真的希望人们不要权威地陈述他们的观点,就像这是一个被广泛接受的智慧或规则。这是很有可能的,Apple 认为人们希望将PHAsset 转换为UIImage,反之亦然。这就是他们为此提供 API 的原因。
【解决方案2】:

聚会有点晚了,但我会为未来的人发布我的答案。

我在我的应用中所做的是截取屏幕截图并保存到照片应用中的专用相册。

下面例子中的getAlbum()只是一个获取相册的辅助方法。

ImageStoreItem 只是一个包含两个字段的包装器:image: UIImageid: String 用于原始 PHAsset 的标识符。

/**
 Saves the image to the album in the Photos app.

 - Throws:
    - `ImageStore.TypeError.accessDenied`
        if the user has denied access to the photo library.
    - An error thrown by `PHPhotoLibrary`.
 */
func saveImage(_ image: UIImage) throws {
    let album = try getAlbum()

    try PHPhotoLibrary.shared().performChangesAndWait {
        let imgReq = PHAssetChangeRequest.creationRequestForAsset(from: image),
            albReq = PHAssetCollectionChangeRequest(for: album)!

        albReq.addAssets([imgReq.placeholderForCreatedAsset] as NSFastEnumeration)
    }
}

/**
 Fetches images in the app album.

 - Throws:
    - `ImageStore.TypeError.accessDenied`
        if the user has denied access to the photo library.
    - An error thrown by `PHPhotoLibrary`.
    - `NSError` thrown by `PHImageManager`
        if fetching images from the `PHAsset` list failed.
    - `Globalerror.unknown` if no image was fetched,
        but there is no corresponding error object.
 - Returns:
    An array of `ImageStoreItem`s with the album items.
 */
func getImages() throws -> [ImageStoreItem] {
    let album  = try ImageStore.shared.getAlbum(),
        assets = PHAsset.fetchAssets(in: album, options: nil)
    let size = UIScreen.main.bounds.size,
        opt  = PHImageRequestOptions()
    opt.isSynchronous = true

    var res = [ImageStoreItem]()
    var err: Error? = nil

    let handler: (PHAsset) -> (UIImage?, [AnyHashable : Any]?) -> Void =
    { (asset) in
        { (image, info) in
            if let image = image {
                let item = ImageStoreItem(image: image,
                                      id: asset.localIdentifier)
                res.append(item)
            } else if let info = info {
                if let error = info[PHImageErrorKey] {
                    err = error as! NSError
                } else {
                    var userInfo = [String : Any]()
                    for (key, value) in info {
                        userInfo[String(describing: key)] = value
                    }

                    err = GlobalError.unknown(info: userInfo)
                }
            }
        }
    }

    assets.enumerateObjects { (asset, _, _) in
        PHImageManager.default()
            .requestImage(for: asset,
                          targetSize: size,
                          contentMode: .default,
                          options: opt,
                          resultHandler: handler(asset))
    }

    if let error = err { throw error }

    return res
}

documentation on the PhotoKit 不是太令人印象深刻,但看看这里和那里你就会掌握它的窍门。

【讨论】:

    猜你喜欢
    • 2015-08-28
    • 2021-12-04
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    相关资源
    最近更新 更多