Banng
Banng

Reputation: 531

Get EXIF metadata in of captured image in swift#3

We are getting EXIF data as blank. We are using Swift3 and iOS10.3 We have referred the URL - UIImagePickerController and extracting EXIF data from existing photos

But, it does not explains about how to do it in Swift.

For taking photo below is our code.

Take Photo

@IBAction func takePhoto(_ sender: AnyObject) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.camera
            imagePicker.allowsEditing = false
            self.present(imagePicker, animated: true, completion: nil)
        }
    }

Getting Photo

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            myImg.contentMode = .scaleToFill
            myImg.image = pickedImage
        }
        picker.dismiss(animated: true, completion: nil)
    }

Saving Photo

@IBAction func savePhoto(_ sender: AnyObject) {
        let imageData = UIImagePNGRepresentation(myImg.image!)
        let compresedImage = UIImage(data: imageData!)
        UIImageWriteToSavedPhotosAlbum(compresedImage!, nil, nil, nil)

        let alert = UIAlertController(title: "Saved", message: "Your image has been saved", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
        alert.addAction(okAction)
        self.present(alert, animated: true, completion: nil)
    }

After this, when we check the properties of Photo - EXIF data is blank.

I have read various articles related to this but not answer related to Swift3. Really appreciate, if someone could please help us on this. Thank you.

Upvotes: 8

Views: 5354

Answers (4)

Zsombor Fuszenecker
Zsombor Fuszenecker

Reputation: 161

**iOS 13, SWIFT 5, using the Photos API:

In order for this to work you will need the app to access the users photo library. To do this add: NSPhotoLibraryUsageDescription to the Info.plist and define why you need access.

enter image description here

Then before showing the picker, ask for access

import Photos


func openPicker() {
    let status = PHPhotoLibrary.authorizationStatus()
    let picker = UIImagePickerController()
    picker.sourceType = .photoLibrary

    if status == .notDetermined {
        PHPhotoLibrary.requestAuthorization({status in
            if status == .authorized {
                self.present(self.picker, animated: true)
            }
          })
    } else if status == .authorized {
        present(picker, animated: true)
    } else {
        print("NO ACCESS")
        return
    }
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let asset = info[UIImagePickerController.InfoKey.phAsset] as! PHAsset

    PHImageManager.default().requestImageDataAndOrientation(for: asset, options: nil) { (data, responseString, imageOrient, info) in
        let imageData: NSData = data! as NSData
        if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
            let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as! [String: Any]
            print("properties: ", imageProperties)
        }
    }

    dismiss(animated: true, completion: nil)
}

Upvotes: 2

Celeste
Celeste

Reputation: 1577

FOR SWIFT 4+

In didFinishPickingMediaWithInfo add this :

 let dictionary : NSDictionary = info[UIImagePickerController.InfoKey.mediaMetadata] 


    let exif = dictionary.value(forKey: "{Exif}") as! NSDictionary
    let xPixels = exif.value(forKey: "PixelXDimension") as! Int 
    let yPixels = exif.value(forKey: "PixelYDimension") as! Int

    print(exif as Any) // EXIF DICTIONARY
    print(xPixels) // exif contents(dimensions)
    print(yPixels)

Upvotes: 1

Bhavesh.iosDev
Bhavesh.iosDev

Reputation: 942

if someone need to extract data from image captured by avcapturesession.

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: 2

ICL1901
ICL1901

Reputation: 7778

It's a bit late to answer this, but I found that this snip provides my required exif data.

import Photos 
import PhotosUI

 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        let assetURL = info[UIImagePickerControllerReferenceURL] as! NSURL
        let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL as URL], options: nil)
        guard let result = asset.firstObject else {
            return
        }

        let imageManager = PHImageManager.default()
        imageManager.requestImageData(for: result , options: nil, resultHandler:{
            (data, responseString, imageOriet, info) -> Void in
            let imageData: NSData = data! as NSData
            if let imageSource = CGImageSourceCreateWithData(imageData, nil) {
                let imageProperties2 = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil)! as NSDictionary
                print("imageProperties2: ", imageProperties2)
            }

        })
        dismiss(animated: true, completion: nil)
    }

Hope this helps

Upvotes: 5

Related Questions