-
-
Save ivanionut/ccdb296756ce16f00dd8 to your computer and use it in GitHub Desktop.
ColdFusion wrapper for Exiv2.exe (a command line utility to extract EXIF data). Much faster than ImageGetEXIFMetaData().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- 2/16/2016 Exiv2(filePath, ExePath) | |
James Moberg - SunStar Media | |
Requires command-line version of Exiv2 http://www.exiv2.org/ | |
All data returned in a struct. Based on filetype & metadata, keys may not always exist. | |
Latitude/Longitude keys w/decimal values added. All dates formatted to M/D/YYYY HH:MM:SS format. | |
Similar to ImageGetEXIFMetaData(imageNew( imageFilePath )), but much faster. (Exiv2 = 16-47ms; CF = 500-920ms) | |
---> | |
<cffunction name="Exiv2" returntype="struct" output="no"> | |
<cfargument name="filepath" type="string" required="true"> | |
<cfargument name="EXEpath" default="C:\Exiv2\Exiv2.exe" type="string" required="false"> | |
<cfset var Temp = {temp="", raw="", thisline="", response={}}> | |
<cfif FileExists(arguments.filepath)> | |
<cfexecute name="#arguments.EXEpath#" arguments="-Pnt #arguments.filepath#" variable="Temp.Raw" timeout="5"></cfexecute> | |
<!--- Space delimited values. key, interpreted (translated) data ---> | |
<cfloop list="#Temp.Raw#" index="Temp.ThisLine" delimiters="#CHR(10)#"> | |
<cfset Temp.ThisLine = Trim(Temp.ThisLine)> | |
<cfif ListLen(Temp.ThisLine, " ") GT 1> | |
<cfset Temp.Temp = trim(ListFirst(Temp.ThisLine, " "))> | |
<cfset Temp.Response["#Temp.Temp#"] = trim(ListRest(Temp.ThisLine, " "))> | |
</cfif> | |
</cfloop><!--- | |
<CFSET Temp.Response["Raw"] = Temp.Raw> ---> | |
<CFIF StructCount(Temp.Response)> | |
<!--- Add decimal Latitude/Longitude ---> | |
<CFSET temp.Response["Latitude"] = 0> | |
<CFSET temp.Response["Longitude"] = 0> | |
<!--- Parse sexagesimal latitude/longitude and convert to decimal ---> | |
<cfif structKeyExists( Temp.Response, "GPSLatitude" ) AND len( Temp.Response[ "GPSLatitude" ] ) AND VAL(Temp.Response[ "GPSLatitude" ]) | |
AND structKeyExists( Temp.Response, "GPSLatitudeRef" ) AND len( Temp.Response[ "GPSLatitudeRef" ] ) | |
AND structKeyExists( Temp.Response, "GPSLongitude" ) AND len( Temp.Response[ "GPSLongitude" ] ) AND VAL(Temp.Response[ "GPSLongitude" ]) | |
AND structKeyExists( Temp.Response, "GPSLongitudeRef" ) AND len( Temp.Response[ "GPSLongitudeRef" ])> | |
<cfset temp.latitudeParts = listToArray(replace(replace(Temp.Response["GPSLatitude"],"""",""), "deg",""""), "'""")> | |
<cfset temp.Response["Latitude"] = (temp.latitudeParts[ 1 ] + (temp.latitudeParts[ 2 ] / 60) + (temp.latitudeParts[ 3 ] / 3600))> | |
<cfif (Temp.Response[ "GPSLatitudeRef" ] IS "South")> | |
<cfset temp.Response["Latitude"] *= -1> | |
</cfif> | |
<cfset temp.longitudeParts = listToArray(replace(replace(Temp.Response["GPSLongitude"],"""",""), "deg",""""), "'""")> | |
<cfset Temp.Response["Longitude"] = ( Temp.longitudeParts[ 1 ] + (Temp.longitudeParts[ 2 ] / 60) + (Temp.longitudeParts[ 3 ] / 3600))> | |
<cfif (Temp.Response[ "GPSLongitudeRef" ] IS "West")> | |
<cfset Temp.Response["Longitude"] *= -1> | |
</cfif> | |
</CFIF> | |
<!--- Parse date Exif values to dates. Consolidate GPSDateStamp & GPSTimeStamp (UTC) ----> | |
<CFLOOP COLLECTION="#Temp.Response#" ITEM="Temp.Temp"> | |
<CFIF Temp.Temp IS "GPSDateStamp" AND ListLen(Temp.Response[Temp.Temp],":") IS 3 AND isDate(replace(Temp.Response[Temp.Temp],":","-", "all"))> | |
<CFIF StructKeyExists(Temp.Response, "GPSTimeStamp") AND ListLen(Temp.Response["GPSTimeStamp"],":") IS 3> | |
<CFSET Temp.Response["GPSDateStamp"] = DateFormat(parseDateTime(replace(Temp.Response[Temp.Temp],":","-", "all")), "M/D/YYYY") & " " & Temp.Response["GPSTimeStamp"]> | |
<CFELSE> | |
<CFSET Temp.Response[Temp.Temp] = DateFormat(parseDateTime(replace(Temp.Response[Temp.Temp],":","-", "all")), "M/D/YYYY") & "00:00:00"> | |
</CFIF> | |
<CFELSEIF Find("DateTime", Temp.Temp) AND ListLen(Temp.Response[Temp.Temp],":") IS 5 AND isDate(replace(replace(Temp.Response[Temp.Temp],":","-"),":","-"))> | |
<CFSET Temp.TempDate = parseDateTime(replace(replace(Temp.Response[Temp.Temp],":","-"),":","-"))> | |
<CFSET Temp.Response[Temp.Temp] = DateFormat(Temp.TempDate,"M/D/YYYY") & " " & TimeFormat(Temp.TempDate,"HH:MM:SS")> | |
</CFIF> | |
</CFLOOP> | |
</CFIF> | |
</cfif> | |
<cfreturn Temp.Response> | |
</cffunction> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment