无法从照片库中的截图PNG文件获取创建日期求助
解决iOS截图PNG无法通过TIFF字典获取创建日期的问题
这个问题我之前也踩过坑!iOS系统通过Home键+电源键生成的PNG截图,确实不会像相机拍摄的JPG那样把创建日期写入TIFF元数据块,所以你通过CIImage读取TIFF字典自然拿不到数据。不过有两个更可靠的方案可以解决:
方案1:直接从PHAsset获取创建日期(推荐)
PHAsset本身就存储了资产的创建日期,这个值是系统相册数据库统一维护的,不管图片是JPG还是PNG(包括截图),都能正确返回。而且这种方式性能更好,不用加载整个图片数据,适合批量遍历。
示例代码:
// 配置获取选项,按创建日期倒序排列 let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] // 获取所有图片资产 let imageAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions) // 遍历资产 imageAssets.enumerateObjects { asset, index, stop in // 直接读取PHAsset的creationDate属性 if let creationDate = asset.creationDate { print("图片创建日期:\(creationDate)") // 这里处理你的业务逻辑 } }
方案2:通过PHAssetResource获取文件本身的元数据
如果你的场景必须从图片文件本身提取元数据(比如需要导出原始文件后读取),可以用PHAssetResource来获取完整的文件数据,再通过CGImageSource解析元数据。iOS截图的PNG文件会把日期存在其他元数据字段里,比如EXIF或者PNG专属的属性中。
示例代码:
let fetchOptions = PHFetchOptions() let imageAssets = PHAsset.fetchAssets(with: .image, options: fetchOptions) imageAssets.enumerateObjects { asset, index, stop in // 获取当前资产的资源对象 let resources = PHAssetResource.assetResources(for: asset) guard let resource = resources.first else { return } // 请求资源数据 let resourceManager = PHAssetResourceManager.default() resourceManager.requestData(for: resource, options: nil) { data, error in guard let data = data, error == nil else { print("获取资源数据失败:\(error?.localizedDescription ?? "未知错误")") return } // 解析图片元数据 if let imageSource = CGImageSourceCreateWithData(data as CFData, nil) { let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [String: Any] // 尝试从PNG属性中读取日期 if let pngProps = properties?[kCGImagePropertyPNGDictionary as String] as? [String: Any], let dateString = pngProps[kCGImagePropertyDateTimeOriginal as String] as? String { print("PNG元数据中的创建日期:\(dateString)") } // 尝试从EXIF属性中读取日期 else if let exifProps = properties?[kCGImagePropertyExifDictionary as String] as? [String: Any], let dateString = exifProps[kCGImagePropertyDateTimeOriginal as String] as? String { print("EXIF元数据中的创建日期:\(dateString)") } } } }
关键说明
- 为什么之前的方法无效?iOS系统截图是直接生成的PNG文件,系统不会像处理相机照片那样,把创建日期写入TIFF元数据块,所以通过
CIImage.properties获取TIFF字典自然是空的。 - 权限注意:确保你的App已经请求了照片库的读写权限(
PHAuthorizationStatus.authorized),否则无法访问PHAsset的属性或资源数据。 - 性能对比:方案1的性能远优于方案2,因为不需要加载整个图片文件,建议优先使用方案1。
内容的提问来源于stack exchange,提问作者pmbenvenuto




