#include <GDIPlus.au3>
Global Enum $iPropertyTagGpsLatitudeRef = 0x0001, $iPropertyTagGpsLatitude, $iPropertyTagGpsLongitudeRef, $iPropertyTagGpsLongitude
_GDIPlus_Startup()
$sFile = FileOpenDialog('Select image file', '', 'Images (*.jpg;*.bmp)')
If @error Then Exit
$hImage = _GDIPlus_ImageLoadFromFile($sFile)
$iLat = _ImageGetGPS($hImage, 'Latitude')
$iLon = _ImageGetGPS($hImage, 'Longitude')
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()
$sXML = BinaryToString(InetRead(StringFormat('http://maps.google.com/maps/api/geocode/xml?latlng=%s,%s&sensor=false', $iLat, $iLon)))
$sLocation = StringRegExpReplace($sXML, '(?si).*?<formatted_address>(.*?)</formatted_address>.*', '$1')
MsgBox(64, 'Image Geolocation', $sLocation)
Func _ImageGetGPS($hImage, $iPropertyTag)
Local $tGPS, $tProp, $iDegrees, $iMinutes, $iSeconds, $tPropRef, $iFlip
$tGPS = _GDIPlus_ImageGetPropertyItem($hImage, Eval('iPropertyTagGps' & $iPropertyTag))
$tProp = DllStructCreate("ulong dd;ulong ddn;ulong mm;ulong mmn;ulong ss;ulong ssn", $tGPS.Value)
$iDegrees = $tProp.ddn > 0 ? ($tProp.dd / $tProp.ddn) : $tProp.dd
$iMinutes = $tProp.mmn > 0 ? ($tProp.mm / $tProp.mmn) : $tProp.mm
$iSeconds = $tProp.ssn > 0 ? ($tProp.ss / $tProp.ssn) : $tProp.ss
$tGPS = _GDIPlus_ImageGetPropertyItem($hImage, Eval('iPropertyTagGps' & $iPropertyTag & 'Ref'))
$tPropRef = DllStructCreate("char ref", $tGPS.Value)
$iFlip = StringRegExp($tPropRef.ref, '(?i)^(W|S)$') ? -1 : 1
return $iFlip * ($iDegrees + ($iMinutes / 60) + ($iSeconds / 3600))
EndFunc
Func _GDIPlus_ImageGetPropertyItem($hImage, $iPropID)
Local $aResult = DllCall($ghGDIPDll, "int", "GdipGetPropertyItemSize", "handle", $hImage, "uint", $iPropID, "ulong*", 0)
If @error Then Return SetError(@error, @extended, 0)
If $aResult[0] Then Return SetError(10, $aResult[0], 0)
Local Static $tBuffer
$tBuffer = DllStructCreate("byte[" & $aResult[3] & "]")
$aResult = DllCall($ghGDIPDll, "int", "GdipGetPropertyItem", "handle", $hImage, "uint", $iPropID, "ulong", $aResult[3], "struct*", $tBuffer)
If @error Then Return SetError(@error, @extended, 0)
If $aResult[0] Then Return SetError(11, $aResult[0], 0)
Local Const $tagGDIPPROPERTYITEM = "uint id;ulong length;word type;ptr value"
Local $tPropertyItem = DllStructCreate($tagGDIPPROPERTYITEM, DllStructGetPtr($tBuffer))
If @error Then Return SetError(20, $aResult[0], 0)
Return $tPropertyItem
EndFunc