iPhone Получить UIImagePickerController Lat/Lng

Я использую UIImagePickerController, чтобы сделать снимок, а затем загрузить его в WCF Service. Вместе с изображением мне также нужно отправить широту и долготу фотографии.

Как я могу получить эту информацию из сделанной фотографии?

Я искал в Интернете, но не могу найти хороший источник информации. Я видел данные EXIF, которые передаются через ключ UIImagePickerControllerMediaMetadata как часть метода делегата didFinishPickingMediaWithInfo. Однако, когда я распечатываю содержимое журнала, информации о местоположении нет.

Я что-то упустил, нужно ли включать службы определения местоположения, прежде чем делать фото? Или есть другой способ получить информацию?

Большое спасибо.


person Dan Ellis    schedule 30.05.2011    source источник


Ответы (4)


Я разбирался в этом пару дней и, наконец, нашел решение. Как уже было предложено, вы можете использовать ALAssetsLibrary.

Средство выбора изображений предоставит вам словарь, содержащий URL-адрес, указывающий на актив.

Метод assetForURL: resultBlock: failureBlock: библиотеки ALAssetsLibrary использует блоки. Подробнее о них можно прочитать в примере здесь. Итак, вот как мы обрабатываем информацию, предоставленную сборщиком:

- (void)imagePickerController:(UIImagePickerController *)picker
            didFinishPickingMediaWithInfo:(NSDictionary *)info
{

    if ([picker sourceType] == UIImagePickerControllerSourceTypePhotoLibrary) {
        // We'll store the info to use in another function later
        self.imageInfo = info;

        // Get the asset url
        NSURL *url = [info objectForKey:@"UIImagePickerControllerReferenceURL"];

        // We need to use blocks. This block will handle the ALAsset that's returned: 
        ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
        {
            // Get the location property from the asset  
            CLLocation *location = [myasset valueForProperty:ALAssetPropertyLocation];
            // I found that the easiest way is to send the location to another method
            [self handleImageLocation:location];
        };
        // This block will handle errors:
        ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
        {
            NSLog(@"Can not get asset - %@",[myerror localizedDescription]);
            // Do something to handle the error
        };


        // Use the url to get the asset from ALAssetsLibrary,
        // the blocks that we just created will handle results
        ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
        [assetslibrary assetForURL:url 
                       resultBlock:resultblock
                      failureBlock:failureblock];

    }
    [picker dismissModalViewControllerAnimated:YES];
    [picker release];
}

И следующий метод, который обрабатывает данные об изображении и местоположении:

- handleImageLocation:(CLLocation *)location 
{
    UIImage *image = [self.imageInfo objectForKey:UIImagePickerControllerOriginalImage];
    // Do something with the image and location data...
}

И, конечно же, вы также можете получить другую информацию об изображении с помощью этого метода, используя ключи:

ALAssetPropertyType
ALAssetPropertyLocation
ALAssetPropertyDuration
ALAssetPropertyOrientation
ALAssetPropertyDate
ALAssetPropertyRepresentations
ALAssetPropertyURLs
person lari    schedule 23.06.2011
comment
Это замечательно, если исходным типом является библиотека, но что, если это камера (UIImagePickerControllerSourceTypeCamera)? В этом случае URL будет равен нулю. :( - person Joe D'Andrea; 17.06.2012
comment
Я получаю ошибку: Argument type 'void' is incomplete при использовании вышеуказанного кода. Любые идеи? - person Shredder2794; 20.05.2014
comment
@ Shredder2794 Shredder2794, к сожалению, в настоящее время я не использую этот код ни в одном из своих проектов, поэтому не могу дать вам хороший ответ. Вы можете отладить, какая именно строка выдает вам эту ошибку? - person lari; 21.05.2014
comment
Вопрос про UIImagePickerControllerSourceTypeCamera довольно старый, но я все равно отвечу. Если вы получаете изображение непосредственно с камеры, вы также можете сами получить местоположение с помощью CLLocationManager. Затем вы должны сохранить изображение в библиотеке фотографий с указанием местоположения в метаданных. На это уже был дан ответ: stackoverflow.com/a/11071064/811830 - person lari; 21.05.2014

Новое с iOS 8

Это было сложно с ALAssetLibrary , который сейчас устарел, используйте Photos.Framework вместо этого.

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    if let assertURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
        let fetchResult = PHAsset.fetchAssetsWithALAssetURLs([assertURL], options: nil)
        if let asset = fetchResult.firstObject as? PHAsset
        {
            print(asset.location)
        }
    }
}

Быстро и просто :)

person Yuchen    schedule 18.03.2016
comment
UIImagePickerControllerReferenceURL в этом случае равен нулю. потому что он еще не сохранен. URL не существует. - person Xu Yin; 27.10.2016
comment
Вы имеете в виду, что info[UIImagePickerControllerReferenceURL] для вас nil? @XuYin - person Yuchen; 27.10.2016

Это "баг", я думаю. UIImagePickerViewController не будет возвращать данные о местоположении изображений, которые вы выбрали из него: как вы обнаружили, они удалены из метаданных.

Однако если вы используете ALAssetLibrary для получения изображений, вы можете получить данные о местоположении (в виде объекта CLLocation, связанного с изображением). В этом вопросе есть некоторый код - проблема ALAsset с изображением iPhone - который поможет вам получить ALAsset от UIImagePickerController.

Конечно, было бы проще, если бы вы могли сразу же получить эту информацию из средства выбора, поэтому подумайте о том, чтобы отправить запрос функции в Apple.

person lxt    schedule 30.05.2011
comment
Спасибо за ваш комментарий. Я просто пытаюсь реализовать код, который вы связали, но всякий раз, когда я пытаюсь получить URL-адрес ссылки на изображение, используя [info objectForKey:UIImagePickerControllerReferenceURL], он просто возвращает NULL. Я предполагаю, что это связано с тем, что сделанное изображение не сохраняется на телефоне (если я выбираю существующую фотографию, она находит URL-адрес в порядке). Если я использую UIImageWriteToSavedPhotosAlbum для сохранения изображения, могу ли я получить от него URL-адрес ссылки? - person Dan Ellis; 30.05.2011

Поскольку ваш исходный тип выглядит как UIImagePickerControllerSourceTypeCamera, это очень быстро разочаровывает, как вы уже знаете. Информация о местоположении, похоже, пропала без вести.

В качестве альтернативы UIImageWriteToSavedPhotosAlbum() (который не относится к сохраненному изображению) я попробовал ALAssetsLibrary и -writeImageToSavedPhotosAlbum:metadata:completionBlock: (используя UIImagePickerControllerMediaMetadata для его заполнения, надеясь, что фреймворк заполнит пробелы информацией о местоположении).

Увы, не повезло. Несмотря на то, что этот метод возвращает URL-адрес сохраненного изображения, я все равно не могу получить от него информацию ALAssetPropertyLocation. Даже если я использую вариант ориентации метода сохранения, это бесполезно.

На данный момент я думаю, что единственным выходом будет включение вашего собственного информация о местоположении, как указано здесь.

Однако мне кажется несколько подозрительным, что мне придется это делать, поскольку я ожидаю, что фреймворк справится с этим автоматически. На самом деле, я даже не могу получить информацию о местоположении для ранее сделанных фотографий. Это со всеми разрешениями, предоставленными во всех нужных местах, независимо от того, какое устройство я использую, iPhone или iPad. (Даже приложение «Камера» имеет надлежащее разрешение, FWIW.)

person Joe D'Andrea    schedule 17.06.2012