在 C# 中从图像的 EXIF 中获取 GPS 数据

Getting GPS data from an image#39;s EXIF in C#(在 C# 中从图像的 EXIF 中获取 GPS 数据)

本文介绍了在 C# 中从图像的 EXIF 中获取 GPS 数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个允许使用 ASP.NET C# 将图像上传到服务器的系统.我正在处理图像,一切都很好.我设法找到一种方法来读取 Date Created EXIF 数据并将其解析为 DateTime.这也很好用.

I am developing a system that allows for an image to be uploaded to a server using ASP.NET C#. I am processing the image and all is working great. I have managed to find a method that reads the Date Created EXIF data and am parsing it as a DateTime. That works great too.

我现在正尝试从 EXIF 读取 GPS 数据.我想捕捉纬度和经度的数字.

I am now trying to read GPS data from the EXIF. I am wanting to capture the Latitude and Longitude figures.

我将此列表用作 EXIF 数据的参考(使用属性项的数字)http://www.exiv2.org/tags.html

I am using this list as a reference to the EXIF data (using the numbers for the property items) http://www.exiv2.org/tags.html

这是捕获创建日期的方法(有效).

Here is the method to capture the date created (which works).

public DateTime GetDateTaken(Image targetImg)
{
    DateTime dtaken;

    try
    {
        //Property Item 306 corresponds to the Date Taken
        PropertyItem propItem = targetImg.GetPropertyItem(0x0132);

        //Convert date taken metadata to a DateTime object
        string sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
        string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
        string firsthalf = sdate.Substring(0, 10);
        firsthalf = firsthalf.Replace(":", "-");
        sdate = firsthalf + secondhalf;
        dtaken = DateTime.Parse(sdate);
    }
    catch
    {
        dtaken = DateTime.Parse("1956-01-01 00:00:00.000");
    }
    return dtaken;
}

下面是我对 GPS 做同样的尝试..

Below is my attempt at doing the same for GPS..

public float GetLatitude(Image targetImg)
{
    float dtaken;

    try
    {
        //Property Item 0x0002 corresponds to the Date Taken
        PropertyItem propItem = targetImg.GetPropertyItem(2);

        //Convert date taken metadata to a DateTime object
        string sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
        dtaken = float.Parse(sdate);
    }
    catch
    {
        dtaken = 0;
    }
    return dtaken;
}

进入 sdate 的值为 "5l d"

The value that's coming out and into sdate is "5l d"

这是来自带有 GPS EXIF 数据的 iPhone 4 拍摄的图像.

And that is coming from an image that was taken by an iPhone 4 which does carry the GPS EXIF data.

我知道有一些课程可以做到这一点,但我更愿意自己编写 - 不过我愿意接受建议 :-)

I know there are classes out there that do this but would prefer to write my own - I am open to suggestions though :-)

提前致谢.

推荐答案

根据tomfanning 在上面发布的链接,属性项 0x0002 是表示为 PropertyTagTypeRational 的纬度.有理类型定义为...

According to the link posted above by tomfanning, property item 0x0002 is the latitude expressed as a PropertyTagTypeRational. The rational type is defined as...

指定值数据成员是一个无符号长整数对数组.每对代表一个分数;第一个整数是分子,第二个整数是分母.

Specifies that the value data member is an array of pairs of unsigned long integers. Each pair represents a fraction; the first integer is the numerator and the second integer is the denominator.

当它实际上只是一系列字节时,您试图将其解析为字符串.根据上述,应该有 3 对 32 位无符号整数打包到该字节数组中,您可以使用以下方法检索:

You are trying to parse it as a string when it's actually just a series of bytes. According to the above, there should be 3 pairs of 32-bit unsigned integers packed into that byte array, which you can retrieve using the following:

uint degreesNumerator   = BitConverter.ToUInt32(propItem.Value, 0);
uint degreesDenominator = BitConverter.ToUInt32(propItem.Value, 4);
uint minutesNumerator   = BitConverter.ToUInt32(propItem.Value, 8);
uint minutesDenominator = BitConverter.ToUInt32(propItem.Value, 12);
uint secondsNumerator   = BitConverter.ToUInt32(propItem.Value, 16);
uint secondsDenominator = BitConverter.ToUInt32(propItem.Value, 20);

在获得这些值后,您如何处理这些值是为了让您自己解决:) 文档是这样说的:

What you do with these values after you've got them is for you to work out :) Here's what the docs say:

纬度表示为三个有理值,分别给出度、分和秒.表示度、分、秒时,格式为dd/1、mm/1、ss/1.当使用度和分时,例如,分钟的小数部分最多保留两位小数,格式为 dd/1、mmmm/100、0/1.

Latitude is expressed as three rational values giving the degrees, minutes, and seconds respectively. When degrees, minutes, and seconds are expressed, the format is dd/1, mm/1, ss/1. When degrees and minutes are used and, for example, fractions of minutes are given up to two decimal places, the format is dd/1, mmmm/100, 0/1.

这篇关于在 C# 中从图像的 EXIF 中获取 GPS 数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:在 C# 中从图像的 EXIF 中获取 GPS 数据

基础教程推荐