2014-11-05 12 views
6

Ich habe eine harte Zeit, weil ich die GPS-Koordinaten von einem Foto extrahieren möchte. Ich benutze die Funktion imagePickerController:didFinishPickingMediaWithInfo, um ein Bild auszuwählen und das Ich füge dieses Bild in eine CollectionView mit dem neuen Photos-Framework ein. Ich möchte die GPS-Koordinaten aus dem Foto extrahieren. Ich habe einige Nachforschungen angestellt und mir ist bewusst, dass UIImage nicht alle Metadaten enthält, also habe ich versucht, das AssetsLibrary Framework zu verwenden. Innen didFinishPickingMediaWithInfo ich den folgenden Code bin mit dem Aufnahmeort zu extrahieren:GPS-Daten vom Foto extrahieren

var referenceURL : NSURL = info.objectForKey(UIImagePickerControllerReferenceURL) as NSURL 
    var library : ALAssetsLibrary = ALAssetsLibrary() 
    library.assetForURL(referenceURL, resultBlock: { (asset : ALAsset!) -> Void in 
     var rep : ALAssetRepresentation = asset.defaultRepresentation() 
     var metadata : NSDictionary = rep.metadata() 


     let location: AnyObject! = asset.valueForProperty(ALAssetPropertyLocation) 
     if location != nil { 
      println(location) 
     } 
     else 
     { 
      println("Location not found") 
     } 


     }) 
    { 
      (error : NSError!) -> Void in 
    } 
jedoch

, ist es nicht die Lage nicht finden, obwohl ich das Bild überprüft, und es enthält EXIF-Metadaten (es enthält auch GPS Standorte, an denen ich interessiert bin). Wie kann ich die Koordinaten vom Foto abrufen?

Antwort

6

fand ich eine Lösung mit dem folgenden Code:

if picker.sourceType == UIImagePickerControllerSourceType.PhotoLibrary 
    { 
     if let currentLat = pickedLat as CLLocationDegrees? 
     { 
      self.latitude = pickedLat! 
      self.longitude = pickedLong! 
     } 
     else 
     { 
     var library = ALAssetsLibrary() 
     library.enumerateGroupsWithTypes(ALAssetsGroupAll, usingBlock: { (group, stop) -> Void in 
       if (group != nil) { 

       println("Group is not nil") 
       println(group.valueForProperty(ALAssetsGroupPropertyName)) 
       group.enumerateAssetsUsingBlock { (asset, index, stop) in 
        if asset != nil 
        { 
        if let location: CLLocation = asset.valueForProperty(ALAssetPropertyLocation) as CLLocation! 
        { let lat = location.coordinate.latitude 
         let long = location.coordinate.longitude 

         self.latitude = lat 
         self.longitude = lat 

         println(lat) 
         println(long) 
         } 
        } 
       } 
      } else 
       { 
       println("The group is empty!") 
       } 
      }) 
      { (error) -> Void in 
       println("problem loading albums: \(error)") 
     } 
    } 
} 

Was sie tut, ist, dass es das gesamte Album liest und druckt die Lage, wenn das Foto, das Eigentum hat, sonst druckt „Standort nicht gefunden“. Dies gilt für jedes Foto im Album. Ich habe eine andere Frage ... Ich möchte die Standortinformationen nur für das Foto anzeigen, das ich ausgewählt habe, nicht für das gesamte Album. Hat jemand eine Ahnung, wie dies erreicht werden kann?

+0

Haben Sie das gleiche Problem, haben Sie es geschafft, eine Lösung zu finden? – TimWhiting

4
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) { 

    if picker.sourceType == UIImagePickerControllerSourceType.PhotoLibrary { 

     let image = info[UIImagePickerControllerOriginalImage] as! UIImage 
     pickedImage.image = image 

     let url = info[UIImagePickerControllerReferenceURL] as! NSURL 
     let library = ALAssetsLibrary()   
     library.assetForURL(url, resultBlock: { (asset) in 
      if let location = asset.valueForProperty(ALAssetPropertyLocation) as? CLLocation { 

       self.latitude = location.coordinate.latitude 
       self.longitude = location.coordinate.longitude 
      } 
      }, failureBlock: { (error: NSError!) in 
       print("Error!") 
     }) 
    } 

    self.dismissViewControllerAnimated(true, completion: nil) 
} 

Schließlich gelang es, dies zu erhalten, nachdem eine Menge verschiedener Möglichkeiten, ist es bemerkenswert schlecht in der Apple-Dokumentation verwiesen (oder ich konnte einfach nicht finde es) versucht. Leider haben Bilder, die nicht durch die App "Kamera" erstellt wurden, keine Standort-Metadaten. Aber es funktioniert gut, wenn sie es tun.

bekam die Antwort von https://stackoverflow.com/a/27556241/4337311

+0

Hallo Tim, bin gerade auf deine Frage gestoßen. Der Code, den Sie mir zur Verfügung gestellt haben, ist ähnlich wie der, den ich benutzt habe. Ich habe einen Ergebnisblock wie folgt geschrieben: var resultBlock: ALAssentsLibraryAssetForURLResultBlock = {(myAsset: ALAsset!) -> Void in} Dann nach 'in' würden Sie Holen Sie sich die vollständigen Metadaten und greifen Sie auf die Eigenschaften zu, an denen Sie interessiert sind. – Cristian

+0

Hallo Christian, ich habe die Antwort hinzugefügt, weil Sie in Ihrer eigenen Antwort gefragt haben, wie Sie nur auf die Metadaten des einzelnen Bildes zugreifen und nicht das ganze Album. Froh, dass du am Ende trotzdem hinkommst – TimWhiting

+1

das funktioniert nur für die Bilder, die es in PhotoLibrary gibt. Was ist mit Kamera? – hussain

8

ALAssetsLibrary in iOS 10. Zum Glück ist veraltet, mit Fotos Rahmen dieses trivial zu implementieren ist. Wenn imagePickerController(_ picker:, didFinishPickingMediaWithInfo) aufgerufen wird, können Sie Standortinformationen durch eine einfache Suche abrufen. Werfen Sie einen Blick auf den folgenden Code:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { 
    if let URL = info[UIImagePickerControllerReferenceURL] as? URL { 
     let opts = PHFetchOptions() 
     opts.fetchLimit = 1 
     let assets = PHAsset.fetchAssets(withALAssetURLs: [URL], options: opts) 
     let asset = assets[0] 
     // The location is "asset.location", as a CLLocation 

// ... Other stuff like dismiss omitted 
} 

Ich hoffe, dies hilft. Dies ist Swift 3, natürlich ..

+0

Haben Sie dies bei der Verwendung der Kamera versucht? Wenn ich versuche auf 'info [UIImagePickerControllerReferenceURL] zuzugreifen als? URL' es kommt immer nil zurück. Ich habe die Anforderungen des Standortmanagers in meiner Info.plist-Datei erfüllt und fordere den Benutzer auf, bei der Verwendung auf seinen Standort zuzugreifen. Es kommt immer noch nil zurück. –

+0

können Sie Code mit Beispiel geben –

+0

@MattLong ja ich tat, und es funktioniert gut. Sehen Sie sich https://gist.github.com/sumitlni/6421aece205ebefa647abe701d2429e0 für einen Überblick an - es ist ein ViewController, den Sie in eine Beispiel-App einbetten können, um den Code in Aktion zu sehen. Dies wurde erfolgreich auf dem Gerät getestet. – LNI