3

BitmapMetadata有没有人使用内部使用 WIC(Windows 成像组件)的 WPFs 类成功读取 GPS 数据?

我有一张图像,其中 Windows (8.1) Explorer 和 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");

altitude(System.Double)、altitudeRef(System.Byte)、longitudeRef(System.String) 和(System.String) 的结果latitudeRef都可以并检索到合理的数据(“510.70”、“0”、“N”、“E”)。

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

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

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

4

2 回答 2

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

编辑以上内容仅适用于较旧的 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); 
} 
于 2015-01-19T23:17:19.847 回答
1

It's probably too late to answer, but the .Proxy values have the following format:

MetaDataValue   "16,0.4965000000000145E"    object {string}

means 16 degrees, 0.49 minutes. So you just have to convert it to minutes AND seconds.

于 2016-03-23T12:43:19.313 回答