Thursday 20 May 2010

It always amazes me how easy it is to find vb samples on the web, so imagine how frustrated I was when I couldn't find this vb code. Anyway now I've written it and geotagged my photos I'll probably never look at this again, so if this helps you tag your photos go ahead and cut and paste it.

'Usage: AdGPS2JPG jpgfilename decimal_Longditude  decimal_Lattitude

Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Collections.Generic
Imports System.IO


Public Class Main

    Sub convertDec2CoordAndBytes(ByVal dec As Decimal, ByRef coord() As UInt32, ByRef vBytes() As Byte)

        Dim degs As UInt32 = Decimal.Floor(dec)
        Dim mm As Decimal = 60 * (dec - degs)
        Dim mins As UInt32 = Decimal.Floor(mm)
        Dim ss As Integer = 60 * (mm - mins)
        Dim secs As UInt32 = Decimal.Round(ss)

        ' convert decimal into coords
        coord(0) = degs
        coord(1) = 1
        coord(2) = mins
        coord(3) = 1
        coord(4) = secs
        coord(5) = 1

        ' convert coords into bytes
        Dim bytes() As Byte
        For i = 0 To 5
            bytes = BitConverter.GetBytes(coord(i))
            For j = 0 To 3
                vBytes(j + (4 * i)) = bytes(j)
            Next j
        Next i

    End Sub

    Sub addImageItem(ByRef photoImage As Image, ByVal itemId As Integer, ByVal type As Integer, ByVal vBytes() As Byte, ByVal cBytes As Integer)

        Dim photoItems As PropertyItem()
        Dim photoItem As PropertyItem = Nothing
        photoItems = photoImage.PropertyItems

        Dim fItemExists As Boolean = False

        For Each photoItem In photoItems
            If photoItem.Id = itemId Then
                fItemExists = True
                Exit For
            End If
        Next

        If fItemExists = False Then
            photoItem.Id = itemId
            photoImage.SetPropertyItem(photoItem)
        End If

        photoItem = photoImage.GetPropertyItem(itemId)
        photoItem.Id = itemId
        photoItem.Type = type
        photoItem.Len = cBytes
        photoItem.Value = vBytes
        photoImage.SetPropertyItem(photoItem)


    End Sub


    Private Sub Main_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim photoFileName As String
        Dim photoImage As Image
        Dim decLatt As Decimal
        Dim decLong As Decimal
        Dim northOrSouth As String = "N"
        Dim eastOrWest As String = "E"

        If My.Application.CommandLineArgs.Count < 3 Then
            MsgBox("Error: parameters missing! Usage: AdGPS2JPG jpgfilename decimal_Longditude  decimal_Lattitude")
            End
        End If

        photoFileName = My.Application.CommandLineArgs(0)

        Try
            decLong = Convert.ToDecimal(My.Application.CommandLineArgs(1))
            If decLong < 0 Then
                decLong = -1 * decLong
                eastOrWest = "W"
            End If
            decLatt = Convert.ToDecimal(My.Application.CommandLineArgs(2))
            If decLatt < 0 Then
                decLatt = -1 * decLatt
                northOrSouth = "S"
            End If
        Catch ex As Exception
            MessageBox.Show("Error: could not load latt/long data - " + ex.Message)
            End
        End Try

        Try
            photoImage = Image.FromFile(photoFileName)
        Catch ex As Exception
            MessageBox.Show("Error: could not load jpg: " + photoFileName + " - " + ex.Message)
            End
        End Try

        Dim coord(6) As UInt32
        Dim vBytes(24) As Byte

        ' Add latt
        Call convertDec2CoordAndBytes(decLatt, coord, vBytes)
        addImageItem(photoImage, 2, 5, vBytes, 24)

        ' Add long
        Call convertDec2CoordAndBytes(decLong, coord, vBytes)
        addImageItem(photoImage, 4, 5, vBytes, 24)

        ' Add lat ref
        vBytes(0) = Asc(northOrSouth)
        vBytes(1) = 0
        addImageItem(photoImage, 1, 2, vBytes, 2)

        ' Add long ref
        vBytes(0) = Asc(eastOrWest)
        vBytes(1) = 0
        addImageItem(photoImage, 3, 2, vBytes, 2)

        ' Add GPS Version
        vBytes(0) = 2
        vBytes(1) = 2
        vBytes(2) = 0
        vBytes(3) = 0
        addImageItem(photoImage, 0, 1, vBytes, 4)

        photoImage.Save(photoFileName + "__TEMP")
        photoImage.Dispose()

        File.Replace(photoFileName + "__TEMP", photoFileName, photoFileName + "__BAK")
        File.Delete(photoFileName + "__BAK")

        End

    End Sub

End Class

Followers