2012-07-19 87 views
0

我在将GPS坐标转换为可作为EXIF信息存储的字节数组时遇到问题。将Lat/Long GPS坐标转换为EXIF Rational字节数组

This questions表明EXIF坐标应该表示为三个有理数:degrees/1, minutes/1, seconds/1。我毫不费力地将小数坐标转换为该坐标。例如42.1234567很容易转换为42/1, 7/1, 24/1

我的问题是,我不明白如何将它表示为一个字节数组,当我将它写入图像EXIF信息。我使用的库叫做ExifWorks,我在VB.NET中使用它。

ExifWorks setProperty方法有三件事:EXIF字段ID,一个字节数组作为数据,以及数据类型。下面是我如何使用它:

ew.SetProperty(TagNames.GpsLatitude, byteArrayHere, ExifWorks.ExifDataTypes.UnsignedRational) 

我也试过:

ew.SetPropertyString(TagNames.GpsLatitude, "42/1, 7/1, 24/1") 

这也不起作用。

所以,我的问题是,如何将度数分秒坐标转换为字节数组?到目前为止,我所尝试过的所有内容最终都会成为无效的EXIF信息,并且不起作用。一般的解决方案很好......不一定要在VB.net中工作。

+0

你或许应该得到的Exif规格(这是在网上公布),看看GPS标签的定义。然后得到一个十六进制编辑器,看看你实际上在写什么文件。另一个有用的工具是exiftool。有趣的是,exiftool显示了您之前链接的JPEG文件的正确GPS数据。 – 2012-07-19 23:12:58

回答

0

我已经想通了。这里的解决方案:

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 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 = Math.Truncate(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(intToByteArray(seconds), 0, result, 16, 4) 
    Array.Copy(intToByteArray(1), 0, result, 20, 4) 

    Return result 
End Function 
0

你会得到更好的精度(0.001弧秒,这是一英寸)​​做

 Dim milliseconds = Math.Truncate(temp* 1000.0) 

    ... 

    Array.Copy(intToByteArray(milliseconds), 0, result, 16, 4) 
    Array.Copy(intToByteArray(1000), 0, result, 20, 4)