如何在 swift 4 中从 UIImage 读取 exif 数据?

Posted

技术标签:

【中文标题】如何在 swift 4 中从 UIImage 读取 exif 数据?【英文标题】:How to read exif data from UIImage in swift 4? 【发布时间】:2018-05-29 10:56:40 【问题描述】:

我有一张包含很多 exif informations 的图片。但是当试图用swift读取exif信息时,它显示的exif信息数量有限。

我试过以下代码:

let data = UIImageJPEGRepresentation(image, 1.0)
let source = CGImageSourceCreateWithData(data! as CFData, nil)
let metadata = (CGImageSourceCopyPropertiesAtIndex(source!, 0, nil))
debugPrint(metadata ?? "nil")

它会打印以下结果:

    
    ColorModel = RGB;
    Depth = 8;
    Orientation = 6;
    PixelHeight = 2448;
    PixelWidth = 3264;
    ProfileName = "sRGB IEC61966-2.1";
    "Exif" =     
        ColorSpace = 1;
        PixelXDimension = 3264;
        PixelYDimension = 2448;
    ;
    "JFIF" =     
        DensityUnit = 0;
        JFIFVersion =         (
            1,
            0,
            1
        );
        XDensity = 72;
        YDensity = 72;
    ;
    "TIFF" =     
        Orientation = 6;
    ;

如何从 UIImage 中读取所有 exif 信息?

【问题讨论】:

你能检查一下我附在那儿的图片吗?有我试图访问的所有图像信息。我的问题是为什么它没有打印所有的 exif 信息。 我无法给你一个好的答案,但我所看到的表明它可能不是你的代码提取的一部分。我只是使用UIImagePickerController 相机和UIImagePickerControllerMediaMetadata 来查看所有EXIF 数据并保存图像。但后来我在所述图像上使用了你的代码(这也是我会做的),发现 CGImageSourceCopyPropertiesAtIndex 只有你发现的 - 一个不完整的数据字典。 仅供参考,这些无济于事,但它们是我保存的关于 Swift 和 EXIF 的其他问题:***.com/questions/43920643/modifying-image-metadata***.com/questions/37992611/…***.com/questions/40175160/exif-data-read-and-write 【参考方案1】:

如果您的图像是使用 avcapturesession 捕获的,那么以下是提取 exif 数据的代码。

photoFileOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: (sampleBuffer, error) in
                if (sampleBuffer != nil) 
                        let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer!)
                        let image = self.processPhoto(imageData!)
                        let source: CGImageSource = CGImageSourceCreateWithData((imageData as! CFMutableData), nil)!

                        let metadata = CGImageSourceCopyPropertiesAtIndex(source, 0,nil) as! [String:Any]

                        print("exif data = \(metadata![kCGImagePropertyExifDictionary as String] as? [String : AnyObject]) ")

                        completionHandler(true)
                     else 
                        completionHandler(false)
                    
                

【讨论】:

【参考方案2】:

我怀疑UIImageJPEGRepresentation 函数是罪魁祸首,因为它执行从 HEIC 到 JPEG 的转换(假设您从照片应用程序中提取图像)。在此转换过程中,许多有价值的 Exif 标签(包括地理位置等)似乎都丢失了。

【讨论】:

【参考方案3】:

如果你有图像数据,你可以用它创建一个 CIImage 并读取它的属性,你会在那里找到 EXIF 数据。我尝试使用 UIImage,获取 JPEG 数据并从那里读取 EXIF,但我只得到了与您在帖子中打印的相同的值。我认为一些 EXIF 的东西在 jpeg 转换中被去掉了。通过使用 CIImage,我可以获得 LensMode、ISO、曝光时间等。

这是一个使用 PHImageManager 的示例,我在其中读取所有图像并打印 EXIF 数据

private func getPhotos() 
        let manager = PHImageManager.default()
        let requestOptions = PHImageRequestOptions()
        requestOptions.isSynchronous = true
        requestOptions.deliveryMode = .fastFormat
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

        let results: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
        if results.count > 0 
            for i in 0..<results.count 
                let asset = results.object(at: i)
                manager.requestImageDataAndOrientation(for: asset, options: requestOptions)  (data, fileName, orientation, info) in
                    if let data = data,
                       let cImage = CIImage(data: data) 
                        let exif = cImage.properties["Exif"]
                        print("EXIF Data: \(exif)")
                    
                
            
        
    

【讨论】:

以上是关于如何在 swift 4 中从 UIImage 读取 exif 数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中从文件夹中获取 UIImage 数组?

如何在swift中从UIImage获取图像扩展/格式

在swift 5中从UIImage中删除白色背景

在swift中从UIImage / CGImage获取像素数据作为数组

如何在 swift 中从 nsimage 创建灰度图像?

来自 UIImage 或来自文件的 vImage - Swift 和 Accelerate 框架