0

If I right click the details on an image I get the following under GPS

enter image description here

When querying the EXIF (GpsLatitude and GpsLongitude) data I get

enter image description here

and

enter image description here

I can see that rows 0 and 8 are the degrees and minutes, but the rest makes no sense. What am I missing?

Thank you

gchq
  • 1,603
  • 2
  • 27
  • 52

2 Answers2

2

Exif stores latitude and longitude as three rational numbers (fractions) where the numerator and denominator are four bytes long.

In your example, you are only showing the first 14 values. There are 24 bytes of values to consider.

Specifically, the latitude hours value is 0x00000027 / 0x00000001, or 39 / 1.

Note that the values are stored little endian, so the bytes must be reversed.

By only taking the bytes 0/8/16, you are potentially missing values that spill into the other bytes, and you're also assuming the denominator is always one.


It's likely much easier to use a library to extract this information from your images. I maintain such a library for .NET which will work with VB.NET just fine, and has full support for Exif and many other kinds of metadata from many file formats.

If you're interested, take a look at https://github.com/drewnoakes/metadata-extractor-dotnet

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • I have marked that up, and as the answer... Will your library also work by passing Byte() or BitMap? We process a lot of images and don't want to start writing them to file – gchq Aug 28 '17 at 00:29
  • @gchq There is no need to write the data to a file. You can operate from a byte array or a stream. ImageMetadataReader is a good place to start. – Drew Noakes Aug 28 '17 at 05:30
0

Can't get the last set to show the decimal place (ToDouble doesn't work), but this is very close

 If Not vLong Is Nothing Then
                    vLong1 = BitConverter.ToUInt32(vLong, 0)
                    vLong2 = BitConverter.ToUInt32(vLong, 8)
                    vLong3 = BitConverter.ToUInt32(vLong, 16)
                    vLongDecode = CType(vLong1, String) & " " & CType(vLong2, String) & " " & CType(vLong3, String)
                End If
                If Not vLat Is Nothing Then
                    vLat2 = BitConverter.ToUInt32(vLat, 8)
                    vLat1 = BitConverter.ToUInt32(vLat, 0)
                    vLat3 = BitConverter.ToUInt32(vLat, 16)
                    vLatDecode = CType(vLat1, String) & " " & CType(vLat2, String) & " " & CType(vLat3, String)
                End If
gchq
  • 1,603
  • 2
  • 27
  • 52