WIC/WPF:System.GPS.Longitude和System.GPS.Latitude总是返回NULL(通过BitmapMetadata)

spr*_*y76 3 .net c# windows wpf wic

有没有人使用BitmapMetadata内部使用WIC(Windows Imaging Component)的WPF类成功读取GPS数据?

我有一个图像,其中Windows(8.1)资源管理器和XnView等外部工具显示GPS坐标.

我尝试使用类BitmapMetadata通过Metadata类的属性提取这些数据BitmapFrame:

var md = (BitmapMetdata)extractedFrame.Metadata;
var altitude = md.GetQuery("System.GPS.Altitude");
var altitudeProxy = md.GetQuery("System.GPS.Altitude.Proxy");
var altitudeRef = md.GetQuery("System.GPS.AltitudeRef");
var longitude = md.GetQuery("System.GPS.Longitude");
var longitudeProxy = md.GetQuery("System.GPS.Longitude.Proxy");
var longitudeRef = md.GetQuery("System.GPS.LongitudeRef");
var latitude = md.GetQuery("System.GPS.Latitude");
var latitudeProxy = md.GetQuery("System.GPS.Latitude.Proxy");
var latitudeRef = md.GetQuery("System.GPS.LatitudeRef");
Run Code Online (Sandbox Code Playgroud)

的结果altitude(System.Double),altitudeRef(System.Byte),longitudeRef(System.String)和latitudeRef(System.String)都确定和检索合理的数据( "510.70", "0", "N", "E").

longitude并且latitude应该是System.Double的数组,但它们始终为NULL.

使用".Proxy"后缀的结果返回奇怪的String数据,我不知道如何解析它们以及它们是否是文化不变的:MSDN文档告诉一些不同的东西,没有关于字符串的东西; 但至少那里有经度和纬度的"有效"数据.

错过了什么是错误或我的错?

Cod*_*key 7

我在这里使用代码来访问纬度和经度:http://khason.net/blog/how-to-read-gps-metadata-from-image/ 它不处理N,S,E,W +/ - 虽然部分.因此,您必须使用上面的LongitudeRef和LatitudeRef来确定是否更改坐标上的符号.基本上:

JpegBitmapDecoder decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.None);
BitmapMetadata meta = (BitmapMetadata)decoder.Frames[0].Metadata;
ulong[] latitude    = meta.GetQuery("/app1/ifd/gps/subifd:{ulong=2}") as ulong[];
ulong[] longitude   = meta.GetQuery("/app1/ifd/gps/subifd:{ulong=4}") as ulong[];
double lat          = ConvertCoordinate(latitude);
double longit       = ConvertCoordinate(longitude);

static double ConvertCoordinate(ulong[] coordinates)
{
    int lDash   = (int)(coordinates[0] - ((ulong)0x100000000));
    int lF      = (int)(coordinates[1] - ((ulong)0x100000000));
    double lR   = ((double)(coordinates[2] - ((ulong)0x6400000000))) / 100;
    double tRes = (lDash + (((double)lF) / 60)) + (lR / 3600);
    return (Math.Floor((double)(tRes * 1000000)) / 1000000);
}
Run Code Online (Sandbox Code Playgroud)

编辑上面只适用于较旧的EXIF格式.较新的格式在坐标上有更多的数字,因此它们被错误地转换.我不得不将转换坐标更新为:

static double ConvertCoordinate(ulong[] coordinates)
{
    if (coordinates == null)
        return 0;

    double degrees = ConvertToUnsignedRational( coordinates[ 0 ] ); 
    double minutes = ConvertToUnsignedRational( coordinates[ 1 ] ); 
    double seconds = ConvertToUnsignedRational( coordinates[ 2 ] ); 
    return degrees + (minutes / 60.0) + (seconds / 3600); 

}
static double ConvertToUnsignedRational( ulong value ) 
{ 
    return (value & 0xFFFFFFFFL) / (double) ((value & 0xFFFFFFFF00000000L) >> 32); 
} 
Run Code Online (Sandbox Code Playgroud)