UIImage转换为PHAsset

10

我试图将UIImage转换为PHAsset,但没找到任何解决方案。我只找到了相反的操作(即从PHAssetUIImage)。

场景是这样的,我从自定义目录获取图像到PHAssetCollection中,并在UICollectionView中显示。我还想在此处包括来自上一个屏幕的几张图片,它们来自远程源。我不想将远程图像保留到我的目录中,但想在我的UICollectionView中包含它们。

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


2
找到任何解决方案了吗?我也遇到了同样的问题。 - Ankita Shah
2个回答

0

虽然来晚了,但我会为未来的人们发帖回答。

在我的应用程序中,我采用了截屏并保存到照片应用程序中的专用相册。

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
}

PhotoKit文档并不是很令人印象深刻,但是在这里和那里看一下,你就会掌握它的要领。


-2

您不应该将PHAsset转换为UIImage。我不确定是否可能,但它不应该是可能的,因为PHAssetUIImage具有不同的属性、行为等。反之则可以,因为UIImage的所有属性都可以从PHAsset中派生,但反过来不行。

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


2
我不同意 - 我有一个类似的情况,当呈现一组附件数据时,我会在UICollectionView中呈现一组缩略图图标。当从相机获取附件数据时,它返回为UIImage。但是,其他类型的附件可能是由URL引用的文件。然后使用此URL来确定在didSelect(at index)方法中如何呈现附件。因此,将翻译为PHAsset的目的是获取assets-library方案中的URL。 - Stan
我真的希望人们不要像它是广泛接受的智慧或规则一样权威地陈述他们的观点。这是非常可能的,而且苹果认为人们想要将PHAsset转换为UIImage,反之亦然。这就是为什么他们提供了一个API。 - funct7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接