How to read exif data from UIImage in swift 4?
Asked Answered
O

3

8

I have an image with a-lot of exif informations. But when trying to read the exif information with swift, it shows limited number of exif information.

I have tried following code:

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

And it prints the following result:

    {
    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;
    };
}

How can I read all the exif information from UIImage?

Octroi answered 29/5, 2018 at 10:56 Comment(3)
Can you please check the image I have attached there? There are all the information of image which i am trying to access. My question is why it is not printing all the exif information.Octroi
I'm unable to give you a good answer, but what I'm seeing suggests that it may not be part of what your code pulls out. I just used the UIImagePickerController camera and UIImagePickerControllerMediaMetadata to see all the EXIF data and saved the image. But then I used your code (which is what I'd do also) on said image and found that CGImageSourceCopyPropertiesAtIndex only had what you found - an incomplete dictionary of data.Dustpan
FYI, these won't help but they are the other questions I've saved about Swift and EXIF: https://mcmap.net/q/538508/-modifying-image-metadata #37993111 https://mcmap.net/q/527105/-exif-data-read-and-writeDustpan
S
6

if your image is captured using avcapturesession.than following is code for extract exif Data.

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)
                    }
                }
Savill answered 26/10, 2018 at 9:50 Comment(0)
Y
5

My suspicion is UIImageJPEGRepresentation function is the culprit as it does the conversion from HEIC to JPEG (assuming you're pulling images from the Photos app). A lot of valuable Exif tags, including things like geo-location seem to get lost during this conversion.

Yttrium answered 9/11, 2018 at 9:1 Comment(0)
I
-1

If you have the image Data, you can create a CIImage with it and read its properties, you'll find the EXIF data there. I tried with a UIImage, get the JPEG data and read the EXIF from there, but I only got the same values you printed in your post. I think some of the EXIF stuff is stripped out in the jpeg conversion. By using CIImage I'm able to get LensMode, the ISO, Exposure time etc.

Here is an example with PHImageManager where I read all the images and print EXIF data

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)")
                    }
                }
            }
        }
    }
Inutility answered 23/10, 2020 at 17:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.