You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将PHAsset数组转换为UIImage数组?

将PHAsset数组转换为UIImage数组的实现方案

当然可以搞定这个需求!你已经成功拿到PHAsset数组了,接下来只需要借助PHImageManager来异步请求每个资产对应的UIImage就行。下面给你两种实用的实现方式,适配不同场景:

方式一:异步批量转换(推荐用于大量图片)

因为加载相册图片是异步操作,直接同步处理容易卡主线程,所以用DispatchGroup来管理所有请求的完成状态,最后统一返回结果,还能保证图片顺序和原数组一致:

import Photos

// 先定义个回调类型,方便处理转换完成后的结果
typealias ImageConversionHandler = ([UIImage]) -> Void

func convertAssetsToImages(assets: [PHAsset], completion: @escaping ImageConversionHandler) {
    var resultImages = [UIImage]()
    let group = DispatchGroup()
    
    for asset in assets {
        group.enter()
        
        // 配置图片请求选项
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = false // 异步请求,不卡主线程
        requestOptions.deliveryMode = .highQualityFormat // 优先拿高质量图
        requestOptions.resizeMode = .none // 要原图就用这个,要缩略图就设targetSize
        
        // 发起图片请求
        PHImageManager.default().requestImage(
            for: asset,
            targetSize: PHImageManagerMaximumSize, // 取原始尺寸,按需调整
            contentMode: .aspectFit,
            options: requestOptions
        ) { image, _ in
            if let validImage = image {
                resultImages.append(validImage)
            }
            group.leave()
        }
    }
    
    // 所有请求完成后,回到主线程回调结果
    group.notify(queue: .main) {
        completion(resultImages)
    }
}

// 调用示例
// 先执行你原有的getImages()拿到PHAsset数组
getImages()
convertAssetsToImages(assets: images) { uiImages in
    // 这里就是转换好的UIImage数组啦,随便造作
    print("转换完成,共\(uiImages.count)张图")
}

方式二:同步转换(仅适合少量图片)

如果只是处理几张图,也可以用同步请求的方式,但记得要在后台线程执行,别卡UI:

func convertAssetsToImagesSync(assets: [PHAsset]) -> [UIImage] {
    var resultImages = [UIImage]()
    
    for asset in assets {
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true // 同步请求
        
        var fetchedImage: UIImage?
        PHImageManager.default().requestImage(
            for: asset,
            targetSize: PHImageManagerMaximumSize,
            contentMode: .aspectFit,
            options: requestOptions
        ) { image, _ in
            fetchedImage = image
        }
        
        if let image = fetchedImage {
            resultImages.append(image)
        }
    }
    
    return resultImages
}

// 调用示例(一定要放后台线程!)
DispatchQueue.global().async {
    let convertedImages = self.convertAssetsToImagesSync(assets: self.images)
    DispatchQueue.main.async {
        // 回到主线程更新UI或者做其他操作
    }
}

几个要注意的点

  • 权限检查:别忘了在Info.plist里加NSPhotoLibraryUsageDescription,申请相册访问权限,不然会直接崩溃。
  • 内存优化:如果要加载很多大图,建议设置合适的targetSize,别一股脑全加载原图,内存会爆的。
  • 顺序问题:第一种异步方式里,我们是按原数组顺序逐个添加图片的,所以最终的UIImage数组顺序和PHAsset数组完全一致,不用担心乱序。

内容的提问来源于stack exchange,提问作者xhiza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:49:41