6

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?

steveSarsawa
  • 1,559
  • 2
  • 14
  • 31
Dinesh Kc
  • 91
  • 1
  • 4
  • 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. – Dinesh Kc May 29 '18 at 11:06
  • 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. –  May 29 '18 at 22:23
  • FYI, these won't help but they are the other questions I've saved about Swift and EXIF: https://stackoverflow.com/questions/43920643/modifying-image-metadata https://stackoverflow.com/questions/37992611/swift-how-to-modify-exif-info-in-images-taken-from-mobile-camera https://stackoverflow.com/questions/40175160/exif-data-read-and-write –  May 29 '18 at 22:24

3 Answers3

5

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)
                    }
                }
Bhavesh.iosDev
  • 924
  • 9
  • 27
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.

Chris Kobrzak
  • 1,044
  • 14
  • 20
-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)")
                    }
                }
            }
        }
    }