36

iOSデバイスのカメラで撮影した画像のGPS座標を取得する必要があります。カメラロールの画像は気にせず、UIImagePickerControllerSourceTypeCameraで撮影した画像だけを気にします。

UIImageからExifデータを取得するなど、多くのスタックオーバーフローの回答を読みました-UIImagePickerControllerは、カメラ画像では機能しないように見えるAssetsLibraryフレームワークを使用していることを前提としているか、CoreLocaitonを使用してアプリから緯度/経度を取得します画像からではなく、それ自体。

CoreLocationの使用はオプションではありません。シャッターボタンを押したときの座標はわかりません。(CoreLocationベースのソリューションでは、カメラビューを表示する前または後に座標を記録する必要があります。もちろん、デバイスが移動している場合、座標は間違っています。この方法は、静止したデバイスで機能するはずです。)

私はiOS5のみなので、古いデバイスをサポートする必要はありません。これも商用製品用なので、http://code.google.com/p/iphone-exif/は使用できません。

では、iOS5のカメラから返された画像からGPSデータを読み取るための私のオプションは何ですか?今私が考えることができるのは、画像をCamera Rollに保存してから、AssetsLibraryを使用することだけですが、それはおかしなことに思えます。

ありがとう!


これが私がカレブの答えに基づいて書いたコードです。

    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;
        };
    }

緯度/経度はありません。

4

9 に答える 9

17

問題は、iOS 4UIImage *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;
    };
}
于 2012-09-02T19:57:56.337 に答える
13

私たちはカメラで多くの作業を行ってきましたが、UIImagePickerController少なくとも iOS 5.1.1 までは、 で撮影された写真またはビデオのメタデータで位置データを返しませんUIImagePickerController

カメラ アプリで位置情報サービスが有効になっているかどうかは問題ではありません。これは、 内のカメラ機能ではなく、カメラ アプリの位置情報サービスの使用を制御しますUIImagePickerController

アプリはこのCLLocationクラスを使用して場所を取得し、カメラから返された画像またはビデオに追加する必要があります。アプリが位置情報を取得できるかどうかは、ユーザーがアプリの位置情報サービスへのアクセスを承認しているかどうかによって異なります。また、ユーザーはサービスを介していつでもアプリ (またはデバイス全体) の位置情報サービスを無効にできることに注意してくださいSettings > Location

于 2012-07-06T17:29:02.230 に答える
5

投稿したコードでカメラからの画像データを使用しておらず、そのJPEG表現を生成しました。これにより、基本的にすべてのメタデータが破棄されます。image.CGImageカレブが提案したように使用してください。

また:

これも商用製品用なので、http://code.google.com/p/iphone-exif/は使用できません。

著者は、商用ライセンスが利用可能であると非常に明確に述べています。

于 2012-04-26T18:28:40.500 に答える
4

1つの可能性は、カメラが表示されているときにCoreLocationを実行したままにすることです。サンプルの時間とともに、各CCLocationを配列に記録します。写真が戻ってきたら、その時間を見つけて、配列から最も近いCClocationを一致させます。

ぎこちなく聞こえますが、動作します。

于 2012-04-27T13:22:02.497 に答える
3

私自身のものでこれを正確に行う必要があるとは言えませんが、ドキュメントから、使用している場合、ユーザーがデリゲートメソッドUIImagePickerControllerから取得したばかりの画像を取得できることは明らかです。-imagePicker:didFinishPickingMediaWithInfo:キーUIImagePickerControllerOriginalImageを使用して画像を取得します。

画像を取得したら、 QA1654 Accessing image properties with ImageIOで説明されているように、EXIF データを含むそのプロパティにアクセスできるはずです。CGImageSource を作成するには、UIImage のメソッドCGImageSourceCreateWithData()から取得したデータを見て使用します。CGImage画像ソースを取得したら、 を介してさまざまな属性にアクセスできますCGImageSourceCopyProperties()

于 2012-04-26T17:00:31.793 に答える
0

迅速な回答:

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)")
        })
    }
}
于 2016-11-01T08:06:03.330 に答える
0

これは 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);
        }];

    }

}
于 2014-09-23T07:25:24.800 に答える
-1

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.
}
于 2012-05-02T17:28:04.033 に答える