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, за съжаление в момента не използвам този код в нито един от моите проекти, така че не мога да ви дам добър отговор. Можете ли да отстраните грешки, кой точно ред ви дава тази грешка? - 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 обект, свързан с изображението). Има някакъв код в този въпрос - iphone изображение ALAsset проблем - който ще ви помогне да получите 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, това става много разочароващо много бързо, както вече знаете. Информацията за местоположението изглежда е MIA.

Като алтернатива на UIImageWriteToSavedPhotosAlbum() (което не се отнася за запазеното изображение) опитах ALASsetsLibrary и -writeImageToSavedPhotosAlbum:metadata:completionBlock: (използвайки UIImagePickerControllerMediaMetadata, за да го попълня, надявайки се рамката да запълни празните места с информация за местоположението).

Уви, няма такъв късмет. Въпреки че този метод връща URL адрес към запазеното изображение, все още не мога да получа ALAssetPropertyLocation информация от него. Дори и да използвам варианта за ориентация на метода за запазване, няма полза от него.

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

Изглежда малко подозрително обаче, че ще трябва да направя това, тъй като бих очаквал рамката да се справи с това автоматично за вас. Всъщност дори не мога да получа информация за местоположението за по-рано направени снимки. Това е с всички разрешения, предоставени на всички правилни места, без значение кое устройство използвам, iPhone или iPad. (Дори приложението Камера има подходящо разрешение, FWIW.)

person Joe D'Andrea    schedule 17.06.2012