从iOS iphone中的相机返回的图像中读取GPS数据

Pau*_*nne 35 camera gps geolocation ios

我需要获取iOS设备相机拍摄的图像的GPS坐标.我不关心相机胶卷图像,只关心用UIImagePickerControllerSourceTypeCamera拍摄的图像.

我已经阅读了很多stackoverflow的答案,比如来自UIImage的Get Exif数据 - UIImagePickerController,它假设你正在使用AssetsLibrary框架,它似乎不适用于相机图像,或者使用CoreLocaiton从应用程序获取纬度/经度本身,而不是图像.

使用CoreLocation 不是一种选择.按下快门按钮时,这不会给我坐标.(借助基于CoreLocation解决方案,您可能需要你带了相机视图之前或之后记录COORDS,当然,如果设备在移动坐标将是错误的.这个方法应该用固定设备工作).

我只是iOS5,所以我不需要支持旧设备.这也适用于商业产品,因此我无法使用http://code.google.com/p/iphone-exif/.

那么,从iOS5中相机返回的图像中读取GPS数据有哪些选择?我现在能够想到的是将图像保存到相机胶卷,然后使用AssetsLibrary,但这看起来很糟糕.

谢谢!


这是我根据Caleb的答案编写的代码.

    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);
Run Code Online (Sandbox Code Playgroud)

我的控制台显示:

    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;
        };
    }
Run Code Online (Sandbox Code Playgroud)

没有纬度/经度.

小智 16

问题是因为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
    }];
Run Code Online (Sandbox Code Playgroud)

输出应该是这样的:

{
    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;
    };
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*kle 13

我们已经使用相机进行了大量工作UIImagePickerController,并且至少包括iOS 5.1.1在内,它不会返回用于拍摄的照片或视频的元数据中的位置数据UIImagePickerController.

是否为Camera应用程序启用了位置服务并不重要; 这可以控制Camera应用程序对位置服务的使用,而不是其中的摄像头功能UIImagePickerController.

您的应用需要使用CLLocation该类来获取位置,然后将其添加到从相机返回的图像或视频中.您的应用是否可以获取该位置取决于用户是否授权访问您的应用的位置服务.请注意,用户可以随时通过Settings > Location服务为您的app(或完全为设备)禁用位置服务.


Jim*_*Jim 5

您没有在发布的代码中使用来自相机的图像数据,而是生成了它的 JPEG 表示,这基本上会丢弃所有元数据。image.CGImage像 Caleb 建议的那样使用。

还:

这也适用于商业产品,因此我无法使用http://code.google.com/p/iphone-exif/

作者非常清楚地说明了商业许可是可用的。


Pau*_*nne 4

一种可能性是当相机可见时让 CoreLocation 保持运行。将每个 CCLocation 与样本时间一起记录到数组中。当照片返回时,找到它的时间,然后匹配阵列中最近的 CClocation。

听起来很笨拙,但它会起作用。