如何将经度和纬度转换为GPS Exif字节数组

时间:2015-04-21 00:57:31

标签: vb.net gps exif data-conversion

我试图将纬度= 8°50'34.46“和经度= 125°9'50.82”放入图像的exif文件中。我正在使用vb.net。

我没有将度数和分钟转换为字节的问题,因为它是一个整数但是当我将具有十进制值的秒(34.46“)转换为字节时。它给出了不同的结果,如0.9856。

请帮助我们如何将带有十进制值的数字转换为字节。

这里是代码:

Private Shared Function intToByteArray(ByVal int As Int32) As Byte()
    ' a necessary wrapper because of the cast to Int32
    Return BitConverter.GetBytes(int)
End Function

Private Shared Function doubleToByteArray(ByVal dbl As Double) As Byte()
    Return BitConverter.GetBytes(Convert.ToDecimal(dbl))
End Function

Private Shared Function doubleCoordinateToRationalByteArray(ByVal doubleVal As Double) As Byte()
    Dim temp As Double

    temp = Math.Abs(doubleVal)
    Dim degrees = Math.Truncate(temp)

    temp = (temp - degrees) * 60
    Dim minutes = Math.Truncate(temp)

    temp = (temp - minutes) * 60
    Dim seconds = temp

    Dim result(24) As Byte
    Array.Copy(intToByteArray(degrees), 0, result, 0, 4)
    Array.Copy(intToByteArray(1), 0, result, 4, 4)
    Array.Copy(intToByteArray(minutes), 0, result, 8, 4)
    Array.Copy(intToByteArray(1), 0, result, 12, 4)
    Array.Copy(doubleToByteArray(seconds), 0, result, 16, 4)
    Array.Copy(intToByteArray(1), 0, result, 20, 4)

    Return result
End Function

2 个答案:

答案 0 :(得分:5)

根据this规范,经度和纬度被编码为

  

<强> PropertyTagTypeRational

     

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

编码布局应为(总共24个字节)

Byte Offset   Length   Encoding   Field
0             4        uint       Degrees Nominator
4             4        uint       Degrees Denominator
8             4        uint       Minutes Nominator
12            4        uint       Minutes Denominator
16            4        uint       Seconds Nominator
20            4        uint       Seconds Denominator

鉴于您的输入使用整个度数和分钟而不是分数,通过使用值1作为分母,您对这两个的编码将正常工作。

对于秒,您拥有浮点值,情况并非如此。你必须使用分母和分母部分将其编码为理性。

我不确定你想要的精度是多少,但是考虑到34.46秒的例子,似乎乘以1000并且使用1000作为分母将足够好:

Dim secondsNominator = Math.Truncate(1000 * seconds)
Dim secondsDenoninator = 1000

然后您的编码功能变为:

Private Shared Function doubleCoordinateToRationalByteArray(ByVal doubleVal As Double) As Byte()
    Dim temp As Double

    temp = Math.Abs(doubleVal)
    Dim degrees = Math.Truncate(temp)

    temp = (temp - degrees) * 60
    Dim minutes = Math.Truncate(temp)

    temp = (temp - minutes) * 60
    Dim secondsNominator = Math.Truncate(1000 * temp)
    Dim secondsDenoninator = 1000

    Dim result(24) As Byte

    ' Degrees (nominator, and 1 for denominator)
    Array.Copy(intToByteArray(degrees), 0, result, 0, 4)
    Array.Copy(intToByteArray(1), 0, result, 4, 4)

    ' Minutes (nominator, and 1 for denominator)
    Array.Copy(intToByteArray(minutes), 0, result, 8, 4)
    Array.Copy(intToByteArray(1), 0, result, 12, 4)

    ' Seconds (1000 for denominator: ms resolution)
    Array.Copy(intToByteArray(secondsNominator), 0, result, 16, 4)
    Array.Copy(intToByteArray(secondsDenominator), 0, result, 20, 4)

    Return result
End Function

答案 1 :(得分:0)

exif数据的GPS纬度和经度是“有理”数据类型,或两个32位整数。例如,要表示34.46,您可以使用两个32位整数3,446(分子)和100(分母),或344,600和10,000。对于度数的整数值,例如,您可以使用分母为1的8。

您可以获得exif规范here