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

如何从用户照片库获取所有PNG文件?Photos框架是否可行?

获取照片库中所有PNG文件的解决方案

Absolutely, using the Photos Framework is exactly the right approach here—UIImagePickerController is great for quick user selection, but it doesn’t support the kind of granular filtering you need. PHFetch is perfect for this task, and it’s straightforward to set up. Here’s how to do it step by step:

1. 先请求照片库权限

First, you need to get the user’s permission to access their photo library. Add the NSPhotoLibraryUsageDescription key to your Info.plist (with a clear explanation of why you need access), then request authorization in code:

import Photos

PHPhotoLibrary.requestAuthorization { status in
    switch status {
    case .authorized:
        // 权限已获取,开始获取PNG文件
        self.fetchPNGAssets()
    case .denied, .restricted:
        // 处理权限拒绝的情况
        print("无法访问照片库,请在设置中开启权限")
    case .notDetermined:
        // 这种情况不会在这里触发,因为我们刚发起请求
        break
    @unknown default:
        break
    }
}

2. 使用PHFetchOptions筛选PNG资产

Create a PHFetchOptions object with a predicate that filters for PNG images. You can use the mediaSubtype property of PHAsset to target PNGs directly:

func fetchPNGAssets() {
    let options = PHFetchOptions()
    // 筛选条件:媒体类型是图片,且子类型为PNG
    options.predicate = NSPredicate(format: "mediaType = %d AND mediaSubtype & %d != 0", 
                                    PHAssetMediaType.image.rawValue, 
                                    PHAssetMediaSubtype.imagePNG.rawValue)
    
    // 按创建日期排序(可选)
    options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
    
    // 获取所有符合条件的资产
    let pngAssets = PHAsset.fetchAssets(with: .image, options: options)
    
    if pngAssets.count == 0 {
        print("未找到PNG文件")
        return
    }
    
    // 遍历资产,获取实际文件内容
    pngAssets.enumerateObjects { asset, index, stop in
        self.getPNGFile(from: asset)
    }
}

3. 提取PNG文件的实际内容

Once you have the PHAsset objects, use PHAssetResourceManager to retrieve the actual PNG data or file URL:

func getPNGFile(from asset: PHAsset) {
    let resources = PHAssetResource.assetResources(for: asset)
    guard let pngResource = resources.first(where: { $0.uniformTypeIdentifier == "public.png" }) else {
        return
    }
    
    let manager = PHAssetResourceManager.default()
    let fileURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(UUID().uuidString).png")
    
    manager.writeData(for: pngResource, toFile: fileURL, options: nil) { error in
        if let error = error {
            print("保存PNG文件失败:\(error.localizedDescription)")
            return
        }
        
        // 现在fileURL指向临时目录中的PNG文件,你可以根据需要使用它
        print("成功获取PNG文件:\(fileURL.path)")
        
        // 如果需要UIImage,也可以从data创建
        if let data = try? Data(contentsOf: fileURL), let image = UIImage(data: data) {
            // 使用image
        }
    }
}

补充说明

  • The mediaSubtype.imagePNG filter works for most cases, but if you encounter any PNGs that aren’t picked up (rare), you can skip the predicate in PHFetchOptions and instead fetch all image assets, then filter them by checking the uniformTypeIdentifier of their resources (like we do in getPNGFile). This is less efficient but more thorough.
  • Remember to handle background threads appropriately—asset fetching and file writing should be done off the main thread to avoid UI freezes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:01:23