iOS: 如何从磁盘上的照片文件中提取缩略图和元数据

iOS: How to extract thumbnail and metadata from photo file on disk

此处的 Apple 文档 https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/capturing_still_and_live_photos/capturing_thumbnail_and_preview_images 解释了如何捕获缩略图。

底部写着

If you requested an embedded thumbnail image, that image isn't directly accessible from the AVCapturePhoto object—it's embedded in the image file data that you get by calling the photo object's fileDataRepresentation() method.

似乎无法将嵌入的缩略图与主照片分开。那么嵌入缩略图是什么意思呢?

我想将 JPG 格式的 AVCapturePhoto 和原始 DNG(都要求嵌入缩略图)保存到 App 的 Documents 目录(我不使用 PhotoKit),然后将其加载回 UIImageView .

我保存的照片是这样的:

if let data = capturePhoto.fileDataRepresentation() {
    data.write(to: documentsPath, options: [])
}

然后像这样将其加载回 UIImage

if let data = FileManager.default.contents(at: path) {
    let image = UIImage(data: data)
}

但最好先加载内嵌的thubmail。如果用户点击查看大图,则加载完整的图像文件。

我还想显示元数据,例如 GPS 位置、闪光灯状态、ISO、快门速度等。我想知道该怎么做。

AVFoundationAVAsset 包装了一些元数据类型,但显然不是 EXIF 数据。如果你想要缩略图,你必须使用 CoreGraphics 框架。此函数获取缩略图(如果存在),将最大边长限制为 512 像素。

public func getImageThumbnail(url: URL) -> CGImage? {
    guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }
    
    let thumbnailOptions: [String: Any] = [
        kCGImageSourceCreateThumbnailWithTransform as String: true,
        kCGImageSourceCreateThumbnailFromImageIfAbsent as String: false, // true will create if thumbnail not present
        kCGImageSourceThumbnailMaxPixelSize as String: 512
    ]
    return CGImageSourceCreateThumbnailAtIndex(imageSource, 0, thumbnailOptions as CFDictionary);
}

对于所有其余元数据,您可以使用 CGImageSourceCopyPropertiesAtIndexCGImageSourceCopyMetadataAtIndex