Чтение данных GPS с изображения, возвращаемого камерой в iOS iphone

Мне нужно получить координаты GPS изображения, снятого с камерой устройства iOS. Меня не интересуют изображения Camera Roll, только изображение, сделанное с UIImagePickerControllerSourceTypeCamera.

Я прочитал много ответов stackoverflow, таких как Get Exif data из UIImage – UIImagePickerController , который предполагает, что вы используете среду AssetsLibrary, которая, похоже, не работает на изображениях с камеры, или используйте CoreLocaiton для получения широты / долготы из приложения а не из образа.

Использование CoreLocation не является вариантом . Это не даст мне координаты при нажатии кнопки спуска затвора. (С решениями, основанными на CoreLocation, вам нужно либо записать координаты, прежде чем вы откроете представление камеры или после, и, конечно, если устройство движется, координаты будут неправильными. Этот метод должен работать со стационарным устройством.)

Я только iOS5, поэтому мне не нужно поддерживать старые устройства. Это также для коммерческого продукта, поэтому я не могу использовать http://code.google.com/p/iphone-exif/ .

Итак, каковы мои возможности для чтения данных GPS с изображения, возвращаемого камерой в iOS5? Все, о чем я могу сейчас думать, это сохранить изображение в Camera Roll, а затем использовать AssetsLibrary, но это кажется hokey.

Благодаря!


Вот код, который я написал на основе ответа Калеба.

UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; NSData *jpeg = UIImageJPEGRepresentation(image,1.0); CGImageSourceRef source ; source = CGImageSourceCreateWithData((__bridge CFDataRef)jpeg, NULL); NSDictionary *metadataNew = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex(source,0,NULL); NSLog(@"%@",metadataNew); 

и моя консоль показывает:

  2012-04-26 14:15:37:137 ferret[2060:1799] { ColorModel = RGB; Depth = 8; Orientation = 6; PixelHeight = 1936; PixelWidth = 2592; "{Exif}" = { ColorSpace = 1; PixelXDimension = 2592; PixelYDimension = 1936; }; "{JFIF}" = { DensityUnit = 0; JFIFVersion = ( 1, 1 ); XDensity = 1; YDensity = 1; }; "{TIFF}" = { Orientation = 6; }; } 

Нет широты / долготы.

9 Solutions collect form web for “Чтение данных GPS с изображения, возвращаемого камерой в iOS iphone”

Проблема в том, что с iOS 4 UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; удаляет геолокацию. Чтобы решить эту проблему, вы должны использовать исходный путь фотографии, чтобы получить доступ к метаданным полного изображения. Что-то вроде этого:

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSURL *referenceURL = [info objectForKey:UIImagePickerControllerReferenceURL]; ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:referenceURL resultBlock:^(ALAsset *asset) { ALAssetRepresentation *rep = [asset defaultRepresentation]; NSDictionary *metadata = rep.metadata; NSLog(@"%@", metadata); CGImageRef iref = [rep fullScreenImage] ; if (iref) { self.imageView.image = [UIImage imageWithCGImage:iref]; } } failureBlock:^(NSError *error) { // error handling }]; 

Результат должен выглядеть примерно так:

 { ColorModel = RGB; DPIHeight = 72; DPIWidth = 72; Depth = 8; Orientation = 6; PixelHeight = 1936; PixelWidth = 2592; "{Exif}" = { ApertureValue = "2.970854"; BrightnessValue = "1.115874"; ColorSpace = 1; ComponentsConfiguration = ( 0, 0, 0, 1 ); DateTimeDigitized = "2012:07:14 21:55:05"; DateTimeOriginal = "2012:07:14 21:55:05"; ExifVersion = ( 2, 2, 1 ); ExposureMode = 0; ExposureProgram = 2; ExposureTime = "0.06666667"; FNumber = "2.8"; Flash = 24; FlashPixVersion = ( 1, 0 ); FocalLength = "3.85"; ISOSpeedRatings = ( 200 ); MeteringMode = 5; PixelXDimension = 2592; PixelYDimension = 1936; SceneCaptureType = 0; SensingMethod = 2; Sharpness = 2; ShutterSpeedValue = "3.9112"; SubjectArea = ( 1295, 967, 699, 696 ); WhiteBalance = 0; }; "{GPS}" = { Altitude = "1167.528"; AltitudeRef = 0; ImgDirection = "278.8303"; ImgDirectionRef = T; Latitude = "15.8235"; LatitudeRef = S; Longitude = "47.99416666666666"; LongitudeRef = W; TimeStamp = "00:55:04.59"; }; "{TIFF}" = { DateTime = "2012:07:14 21:55:05"; Make = Apple; Model = "iPhone 4"; Orientation = 6; ResolutionUnit = 2; Software = "5.1.1"; XResolution = 72; YResolution = 72; "_YCbCrPositioning" = 1; }; } 

Мы много работали с камерой и UIImagePickerController и, по крайней мере, вплоть до iOS 5.1.1, она не возвращает данные о местоположении в метаданных для фотографий или видео, снятых с UIImagePickerController .

Не имеет значения, включена ли служба определения местоположения для приложения «Камера» или нет; это контролирует использование приложениями местоположения камеры, а не функцию камеры в UIImagePickerController .

Вашему приложению нужно будет использовать класс CLLocation чтобы получить местоположение, а затем добавить его к изображению или видео, возвращенному с камеры. Может ли ваше приложение получить местоположение, зависит от того, разрешает ли пользователь доступ к службам местоположения для вашего приложения. Обратите внимание, что пользователь может отключить службы определения местоположения для вашего приложения (или полностью для устройства) в любое время через « Settings > Location Службы Settings > Location .

Одна из возможностей – оставить CoreLocation запущенным, когда камера видна. Запишите каждый CCLocation в массив вместе со временем выборки. Когда фото возвращается, найдите свое время, а затем сопоставьте ближайший CClocation из массива.

Звучит kludgy, но он будет работать.

Вы не используете данные изображения из камеры в коде, который вы опубликовали, вы создали его JPEG-представление, которое по существу отменило бы все метаданные. Используйте изображение. image.CGImage как предположил Калеб.

Также:

Это также для коммерческого продукта, поэтому я не могу использовать http://code.google.com/p/iphone-exif/ .

Автор совершенно четко заявляет, что коммерческое лицензирование доступно.

Не могу сказать, что мне нужно было сделать именно это в моих собственных материалах, но из документов это выглядит довольно ясно, что если вы используете UIImagePickerController вы можете получить изображение, которое пользователь только что взял с -imagePicker:didFinishPickingMediaWithInfo: delegate метод. Для получения изображения используйте ключ UIImagePickerControllerOriginalImage .

После того, как вы получили изображение, вы сможете получить доступ к его свойствам, включая данные EXIF, как описано в QA1654. Доступ к свойствам изображения с помощью ImageIO . Чтобы создать CGImageSource, я бы посмотрел CGImageSourceCreateWithData() и использовал данные, полученные из метода CGImage CGImage . Когда у вас есть источник изображения, вы можете получить доступ к различным атрибутам через CGImageSourceCopyProperties() .

Как указывает Крис Маркл , Apple действительно снимает данные GPS из EXIF. Но вы можете открыть RAW-данные изображения и самостоятельно проанализировать данные или использовать стороннюю библиотеку для этого, например .

Вот пример кода:

 - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info { ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) { ALAssetRepresentation *image_representation = [asset defaultRepresentation]; NSUInteger size = (NSUInteger)image_representation.size; // create a buffer to hold image data uint8_t *buffer = (Byte*)malloc(size); NSUInteger length = [image_representation getBytes:buffer fromOffset: 0.0 length:size error:nil]; if (length != 0) { // buffer -> NSData object; free buffer afterwards NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:size freeWhenDone:YES]; EXFJpeg* jpegScanner = [[EXFJpeg alloc] init]; [jpegScanner scanImageData: adata]; EXFMetaData* exifData = jpegScanner.exifMetaData; id latitudeValue = [exifData tagValue:[NSNumber numberWithInt:EXIF_GPSLatitude]]; id longitudeValue = [exifData tagValue:[NSNumber numberWithInt:EXIF_GPSLongitude]]; id datetime = [exifData tagValue:[NSNumber numberWithInt:EXIF_DateTime]]; id t = [exifData tagValue:[NSNumber numberWithInt:EXIF_Model]]; self.locationLabel.text = [NSString stringWithFormat:@"Local: %@ - %@",latitudeValue,longitudeValue]; self.dateLavel.text = [NSString stringWithFormat:@"Data: %@", datetime]; } else { NSLog(@"image_representation buffer length == 0"); } } failureBlock:^(NSError *error) { NSLog(@"couldn't get asset: %@", error); } ]; } 

В своем делете UIImagePickerController выполните следующие действия:

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSDictionary *metadata = [info valueForKey:UIImagePickerControllerMediaMetadata]; // metadata now contains all the image metadata. Extract GPS data from here. } 

Это проверено на iOS 8 и работает для видео, поэтому оно должно работать аналогично для фотографий с несколькими настройками.

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { NSURL *videoUrl = (NSURL *)[info objectForKey:UIImagePickerControllerMediaURL]; NSString *moviePath = [videoUrl path]; if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath) ) { ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init]; [assetLibrary assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) { CLLocation *location = [asset valueForProperty:ALAssetPropertyLocation]; NSLog(@"Location Meta: %@", location); } failureBlock:^(NSError *error) { NSLog(@"Video Date Error: %@", error); }]; } } 

Быстрый ответ:

 import AssetsLibrary import CoreLocation // MARK: - UIImagePickerControllerDelegate extension ViewController: UIImagePickerControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { defer { dismiss(animated: true, completion: nil) } guard picker.sourceType == .photoLibrary else { return } guard let url = info[UIImagePickerControllerReferenceURL] as? URL else { return } let library = ALAssetsLibrary() library.asset(for: url, resultBlock: { (asset) in guard let coordinate = asset?.value(forProperty: ALAssetPropertyLocation) as? CLLocation else { return } print("\(coordinate)") // Getting human-readable address. let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(coordinate, completionHandler: { (placemarks, error) in guard let placemark = placemarks?.first else { return } print("\(placemark.addressDictionary)") }) }, failureBlock: { (error: Error?) in print("Unable to read metadata: \(error)") }) } } 
  • Приложение отслеживания GPS iOS, которое работает все время
  • Использует ли iPhone / iPad GPS и ГЛОНАСС в одно и то же время? Могу ли я ими управлять?
  • Расстояние между двумя местоположениями GPS, а также трассировка линии маршрута между ними
  • Как сохранить приложение GPS в фоновом режиме без пауз
  • Как избежать пробелов в отслеживании gps на iOS 11
  • Способ определения местоположения iOS для фильтрации недопустимых / неточных местоположений
  • iPhone 4 рассчитает Day Duration программно с широты GPS и дня года
  • WGS84 Высота высоты геоида Высота смещения для внешних данных GPS на IOS
  • Получите GPS без предупреждения с разрешением ROOT (джейлбрейк)
  • Рекурсивный запрос местоположения Xamarin
  • Основы IOS Core Location не работали на симуляторе ios 4.2
  • Interesting Posts

    Firebase & Swift: как использовать другую базу данных для хранения больших файлов?

    Файл OpenTok / OpenTok.h не найден

    reloadData не вызывает cellForRowAtIndexPath

    Создание первого диспетчера просмотра запуска

    Xamarin.forms Pinch и Zoom

    Facebook iOs SDK – разместить предварительно заполненное сообщение на стене пользователя

    void main в разделе реализации класса

    NSURLRequest возвращает NSURLErrorNetworkConnectionLost, но доступность говорит о подключении к сети

    Как создать libssl.a для iOS из исходного кода?

    Проверьте состояние воспроизведения AVPlayer

    Как имитировать двухпроходный жест прокрутки / перетаскивания на симуляторе ios?

    XCode 6.0.1 Поведение: огромные задержки?

    Как обнаружить, когда непрозрачная часть UIImage находится в контакте с другой непрозрачной частью UIImage

    Что вызывает CBCentralManagerStateUnknown в iOS?

    Профиль не соответствует Идентификатор приложения com.domainname.helloworld

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.