#CS
Links:
* http://autoit-script.ru/index.php?topic=21816.msg128138#msg128138
* http://stackoverflow.com/questions/2526304/php-extract-gps-exif-data
* https://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx
* https://www.autoitscript.com/forum/topic/179451-solved-preserve-ascpect-ratio-_gdiplus/?do=findComment&comment=1287798
#CE
#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
; #FUNCTION# ====================================================================================================================
; Name ..........: _GDIPlus_ImageGetPropertyItem
; Description ...: Gets a specified property item (piece of metadata) from this Image object.
; Syntax ........: _GDIPlus_ImageGetPropertyItem($hImage, $iPropID)
; Parameters ....: $hImage - A handle to an image object.
; $iPropID - An integer that identifies the property item to be retrieved.
; Return values .: $tagGDIPPROPERTYITEM structure or 0 on errors
; Author ........: UEZ
; Modified ......:
; Remarks .......:
; Related .......: _GDIPlus_ImageLoadFromFile _GDIPlus_ImageLoadFromStream
; Link ..........: Property Item Descriptions -> http://msdn.microsoft.com/en-us/library/windows/desktop/ms534416(v=vs.85).aspx
; ===============================================================================================================================
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 ;why static? because otherwise it would crash when running it as x64 exe (workaround)
$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