Dinesh Kc
Dinesh Kc

Reputation: 111

How to read exif data from UIImage in swift 4?

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?

Upvotes: 8

Views: 6097

Answers (3)

Gualtiero Frigerio
Gualtiero Frigerio

Reputation: 165

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)")
                    }
                }
            }
        }
    }

Upvotes: -1

Chris Kobrzak
Chris Kobrzak

Reputation: 1412

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.

Upvotes: 5

Bhavesh.iosDev
Bhavesh.iosDev

Reputation: 942

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)
                    }
                }

Upvotes: 6

Related Questions