﻿;-- TIME_STAMP   2018-03-07 22:04:31   v 0.1

; Date: 20.01.2018
#Region ;************ Includes ************
#include-once
#include <GDIPlus.au3>
#EndRegion ;************ Includes ************

#Tidy_Off
Global Const $g__aProperties[25][3] = [ _
	['GPS Latitude Ref.', 	'GPS Breitengrad Ref.', '0x0001'], _
	['GPS Latitude', 		'GPS Breitengrad', 		'0x0002'], _
	['GPS Longitude Ref.', 	'GPS Längengrad Ref.', 	'0x0003'], _
	['GPS Longitude', 		'GPS Längengrad', 		'0x0004'], _
	['GPS Altitude Ref.', 	'GPS Höhe Ref.', 		'0x0005'], _
	['GPS Altitude', 		'GPS Höhe', 			'0x0006'], _
	['GPS ImageDirection', 	'GPS Bildausrichtung', 	'0x0011'], _
	['Picture Description', 'Bildbeschreibung', 	'0x010E'], _
	['Camera Manufacturer', 'Kamerahersteller', 	'0x010f'], _
	['Camera Model', 		'Kameramodell', 		'0x0110'], _
	['Orientation', 		'Orientation', 			'0x0112'], _
	['Software', 			'Software', 			'0x0131'], _
	['Artist', 				'Photograph', 			'0x013B'], _
	['Copyright', 			'Copyright', 			'0x8298'], _
	['Exposure Time', 		'Belichtungszeit', 		'0x829A'], _
	['FNumber', 			'Blende', 				'0x829D'], _
	['ISO Speed Ratings', 	'ISO-Wert', 			'0x8827'], _
	['Exif-Version', 		'Exif-Version', 		'0x9000'], _
	['Date Time Original', 	'Aufnahmedatum',		'0x9003'], _
	['Date Time Digitized', 'Speicherdatum',		'0x9004'], _
	['Exposure Bias Value', 'Belichtungskorrektur', '0x9204'], _
	['Flash', 				'Blitz', 				'0x9209'], _
	['Focal Length', 		'Brennweite', 			'0x920A'], _
	['Exif Image Width', 	'Exif Bildbreite', 		'0xA002'], _
	['Exif Image Height', 	'Exif Bildhöhe', 		'0xA003']]
#Tidy_On

If $__g_hGDIPDll = 0 Then
	_GDIPlus_Startup()
	OnAutoItExitRegister('__IGPI_Exit')
EndIf

Func __IGPI_Exit()
	_GDIPlus_Shutdown()
EndFunc

Func _GDIPlus_GetPropertiesList()
	Return $g__aProperties
EndFunc

; Diese Funktion liest 24 ausgewaehlte Exifdaten (siehe $g__aProperties)
; aus der uebergebenen GDI+ Bitmap aus und gibt diese als String in
; englisch ($iLanguage = 0) oder deutsch ($iLanguage = 1) zurueck
Func _GDIPlus_ImageGetPropertyItems(ByRef $hImage, $iLanguage)
	Local Const $tagGDIPPROPERTYITEM = 'uint id;uint length;ushort type;ptr value;'
	Local $aDim, $aFormat, $aRes, $iSize, $iCount, $tBuffer, $pBuffer, $tGDIPPROPERTYITEM, $sOut
	$aDim = _GDIPlus_ImageGetDimension($hImage)
	If @error Then Return SetError(1, @error, False)
	$aFormat = _GDIPlus_ImageGetPixelFormat($hImage)
	$sOut = StringFormat('%s|%d x %d px  (%s)\r', ($iLanguage ? 'Bildgröße' : 'Picture Dimension'), $aDim[0], $aDim[1], $aFormat[1])
	$aRes = DllCall($__g_hGDIPDll, 'uint', 'GdipGetPropertySize', 'hwnd', $hImage, 'uint*', 0, 'uint*', 0)
	If @error Then Return SetError(2, @extended, False)
	$iSize = $aRes[2] ; $aRes[2] = Total size in bytes
	$iCount = $aRes[3] ; $aRes[3] = Number of property items
	$tBuffer = DllStructCreate('byte[' & $iSize & ']')
	$pBuffer = DllStructGetPtr($tBuffer)
	$aRes = DllCall($__g_hGDIPDll, 'uint', 'GdipGetAllPropertyItems', 'hwnd', $hImage, 'uint', $iSize, 'uint', $iCount, 'ptr', $pBuffer)
	If @error Then Return SetError(3, @extended, False)
	For $i = 0 To $iCount - 1
		$tGDIPPROPERTYITEM = DllStructCreate($tagGDIPPROPERTYITEM, $pBuffer)
		$sOut &= __GDIPlus_ImageGetItemValue($tGDIPPROPERTYITEM, $iLanguage)
		$pBuffer += DllStructGetSize($tGDIPPROPERTYITEM)
		$tGDIPPROPERTYITEM = 0
	Next
	$tBuffer = 0
	Return StringTrimRight($sOut, 1)
EndFunc   ;==>_GDIPlus_ImageGetPropertyItems

Func __GDIPlus_ImageGetItemValue(ByRef $tITEM, $iLanguage = 0)
	Local Const $aFlash[2][2] = [['No', 'Nein'], ['Yes', 'Ja']], $sDel1 = '|', $sDel2 = @CR
	Local Const $aAltRef[2][2] = [['Above sea level', 'Oberhalb des Meeresspiegels'], ['Below sea level', 'Unterhalb des Meeresspiegels']]
	Local Enum $GPSLatRef, $GPSLat, $GPSLonRef, $GPSLon, $GPSAltRef, $GPSAlt, $GPSImgDir, $Description, $Make, $Model, $Orientation, $Software, $Artist, $Copyright, $ExpTime, $FNumber, $ISO, $ExifVer, $DTOrig, $DTDig, $ExpBias, $Flash, $FocLen, $Width, $Height
	Local $iID = DllStructGetData($tITEM, 'id'), $sOut = ''
	Switch $iID
		Case 0x0001 ; GPS LatitudeRef (N/S)
			$sOut = $g__aProperties[$GPSLatRef][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0002 ; GPS Latitude
			$sOut = $g__aProperties[$GPSLat][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0003 ; GPS LongitudeRef (E/W)
			$sOut = $g__aProperties[$GPSLonRef][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0004 ; GPS Longitude
			$sOut = $g__aProperties[$GPSLon][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0005 ; GPS AltitudeRef (above/below sea level)
			$sOut = $g__aProperties[$GPSAltRef][$iLanguage] & $sDel1 & $aAltRef[__GDIPlus_ImageGetValue($tITEM, $iID)][$iLanguage] & $sDel2
		Case 0x0006 ; GPS Altitude
			$sOut = $g__aProperties[$GPSAlt][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0011 ; GPS ImageDirection
			$sOut = $g__aProperties[$GPSImgDir][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x010E ; Bildbeschreibung
			$sOut = $g__aProperties[$Description][$iLanguage] & $sDel1 & BinaryToString(__GDIPlus_ImageGetValue($tITEM, $iID), 4) & $sDel2
		Case 0x010f ; Kamerahersteller
			$sOut = $g__aProperties[$Make][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0110 ; Kameramodell
			$sOut = $g__aProperties[$Model][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0112 ; Orientation
			$sOut = $g__aProperties[$Orientation][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x0131 ; Software
			$sOut = $g__aProperties[$Software][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x013B ; Photograph
			$sOut = $g__aProperties[$Artist][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x8298 ; Copyright
			$sOut = $g__aProperties[$Copyright][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x829A ; Belichtungszeit
			$sOut = $g__aProperties[$ExpTime][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & ' s' & $sDel2
		Case 0x829D ; Blende
			$sOut = $g__aProperties[$FNumber][$iLanguage] & $sDel1 & StringFormat('F %.2f', __GDIPlus_ImageGetValue($tITEM, $iID)) & $sDel2
		Case 0x8827 ; ISO-Wert
			$sOut = $g__aProperties[$ISO][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x9000 ; ExifVersion
			$sOut = $g__aProperties[$ExifVer][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x9003 ; Datum/Zeit der Aufnahme
			$sOut = $g__aProperties[$DTOrig][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x9004 ; Datum/Zeit der Speicherung
			$sOut = $g__aProperties[$DTDig][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & $sDel2
		Case 0x9204 ; Belichtungskorrektur
			$sOut = $g__aProperties[$ExpBias][$iLanguage] & $sDel1 & StringFormat('%.2f', __GDIPlus_ImageGetValue($tITEM, $iID)) & $sDel2
		Case 0x9209 ; Blitz
			$sOut = $g__aProperties[$Flash][$iLanguage] & $sDel1 & $aFlash[__GDIPlus_ImageGetValue($tITEM, $iID)][$iLanguage] & $sDel2
		Case 0x920A ; Brennweite
			$sOut = $g__aProperties[$FocLen][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & ' mm' & $sDel2
		Case 0xA002 ; Bildbreite
			$sOut = $g__aProperties[$Width][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & ' px' & $sDel2
		Case 0xA003 ; Bildhoehe
			$sOut = $g__aProperties[$Height][$iLanguage] & $sDel1 & __GDIPlus_ImageGetValue($tITEM, $iID) & ' px' & $sDel2
	EndSwitch
	Return $sOut
EndFunc   ;==>__GDIPlus_ImageGetItemValue

Func __GDIPlus_ImageGetValue(ByRef $tITEM, $iID)
	Local Const $GDIP_PROPERTYTAGTYPEBYTE = 1
	Local Const $GDIP_PROPERTYTAGTYPEASCII = 2
	Local Const $GDIP_PROPERTYTAGTYPESHORT = 3
	Local Const $GDIP_PROPERTYTAGTYPELONG = 4
	Local Const $GDIP_PROPERTYTAGTYPERATIONAL = 5
	Local Const $GDIP_PROPERTYTAGTYPEUNDEFINED = 7
	Local Const $GDIP_PROPERTYTAGTYPESLONG = 9
	Local Const $GDIP_PROPERTYTAGTYPESRATIONAL = 10
	Local $iSize, $iType, $pValue, $tBuffer, $sOut, $iDeg, $iMin, $iDec
	$iSize = DllStructGetData($tITEM, 'length')
	$iType = DllStructGetData($tITEM, 'type')
	$pValue = DllStructGetData($tITEM, 'value')
	Switch $iType ; der Puffer fuer die Items kann unterschiedliche Strukturen aufweisen
		Case $GDIP_PROPERTYTAGTYPEBYTE ; array of bytes
			$tBuffer = DllStructCreate('byte[' & $iSize & ']', $pValue)
			$sOut = DllStructGetData($tBuffer, 'val1')
		Case $GDIP_PROPERTYTAGTYPEASCII ; null-terminated ASCII string
			$tBuffer = DllStructCreate('byte[' & $iSize & ']', $pValue)
			$sOut = BinaryToString(DllStructGetData($tBuffer, 1))
			$sOut = StringReplace($sOut, Chr(0), '')
		Case $GDIP_PROPERTYTAGTYPESHORT ; array of unsigned short (16-bit)
			$tBuffer = DllStructCreate('ushort', $pValue)
			If $iID = 0x9209 Then ; Blitz
				$sOut = BitAND(DllStructGetData($tBuffer, 1), 1) == 1 ; nur False/True
			Else
				$sOut = DllStructGetData($tBuffer, 1)
			EndIf
		Case $GDIP_PROPERTYTAGTYPELONG ; array of unsigned long (32-bit)
			$tBuffer = DllStructCreate('ulong', $pValue)
			$sOut = DllStructGetData($tBuffer, 1)
		Case $GDIP_PROPERTYTAGTYPERATIONAL ; array of pairs of unsigned long
			$tBuffer = DllStructCreate('ulong val1;ulong val2;ulong val3;', $pValue)
			Switch $iID
				Case 0x0002, 0x0004 ; GPS Latitude und Longitude
					$iDeg = DllStructGetData($tBuffer, 'val1') / DllStructGetData($tBuffer, 'val2')
					$iMin = DllStructGetData($tBuffer, 'val3') / 10000
					$iDec = $iMin / 60 + $iDeg
					$sOut = StringFormat('%i  %.4f  (%f)', $iDeg, $iMin, $iDec)
				Case 0x0006 ; GPS Altitude
					$sOut = StringFormat('%.2f m', DllStructGetData($tBuffer, 'val1') / 100)
				Case 0x0011 ; GPS ImageDirection
					$sOut = StringFormat('%.2f', DllStructGetData($tBuffer, 'val1') / 100)
				Case 0x829A ; Belichtungszeit
					$sOut = DllStructGetData($tBuffer, 'val1') & '/' & DllStructGetData($tBuffer, 'val2')
				Case 0x829D, 0x920A ; Blende und Brennweite
					$sOut = DllStructGetData($tBuffer, 'val1') / DllStructGetData($tBuffer, 'val2')
			EndSwitch
		Case $GDIP_PROPERTYTAGTYPEUNDEFINED ; 4 Byte ASCII string
			$tBuffer = DllStructCreate('byte[4]', $pValue)
			$sOut = BinaryToString(DllStructGetData($tBuffer, 1))
		Case $GDIP_PROPERTYTAGTYPESRATIONAL ; array of pairs of signed long
			$tBuffer = DllStructCreate('long val1;long val2;', $pValue)
			$sOut = DllStructGetData($tBuffer, 'val1') / DllStructGetData($tBuffer, 'val2')
	EndSwitch
	$tBuffer = 0
	Return $sOut
EndFunc   ;==>__GDIPlus_ImageGetValue
