Lazycat Posted August 7, 2004 Share Posted August 7, 2004 (edited) Here is my attempt to make UDF for retrieving EXIF info from JPEG's in "right way". Not sure it will work with edited images, and currently it don't work with EXIF's have straight byte order (for ex. all Casio cameras). But it work fine with all images I have from other cameras (7 different models). If you know how you are welcome to add other parameters (Shutter Speed, Aperture etc.) Example: $file = FileOpenDialog("Please select file", "", "JPEG files (*.jpg;*.jpeg)"); if @error then Exit $aExif = _GetEXIFData($file) if @error then Exit $aLabel = StringSplit("Date/Time: |Vendor: |Model: |Descr: |Copyright: |Orientation: |Width: |Height: _ |Original Date: |Digitized Date: |Comments: ", "|") Dim $out = "" for $i = 0 to UBound($aExif)-1 $out = $out & $aLabel[$i+1] & $aExif[$i] & @CR next MsgBox (0, "EXIF Data", $out) UDF: expandcollapse popup;=============================================================================== ; ; Description: Reads EXIF info ; Parameter(s): File name ; Requirement(s): None ; Return Value(s): On Success - array with EXIF data: ; 0 - Date & Time ; 1 - Camera Vendor ; 2 - Camera Model ; 3 - Image Description ; 4 - Copyright ; 5 - Orientation ; 6 - Width ; 7 - Height ; 8 - Original Date & Time ; 9 - Digitized Date & Time ; 10 - User Comments ; On Failure empty string and sets @ERROR: ; 1 - File is not JPEG file ; 2 - EXIF info not found ; Author(s): YDY (Kot) <mpc@nm.ru> ; Version: 1.1.00 ; Date: 09.08.2004 ; Note(s): None ; ;=============================================================================== Func _GetEXIFData($file) Local $pos = 3 If not (_FileReadAtOffsetHEX ($file, 1, 2) = "FFD8") Then SetError(1); Not JPEG Return("") Endif $fs = FileGetSize($file) While $pos < $fs $data = _FileReadAtOffsetHEX ($file, $pos, 4) If StringLeft($data, 2) = "FF" then; Valid segment start $segtype = StringMid($data, 3, 2) if $segtype = "E1" then Return(ParseExif($pos)) $pos = $pos + Dec(StringRight($data, 4)) + 2 Else Exitloop Endif Wend SetError(2); Segment not found Return("") Endfunc Func ParseExif($exif_offset) Local $ByteOrder = 0 Local $ic, $idf_offset, $exif[11] Local $orient = StringSplit("Normal|Mirrored|180░|180░ and mirrored|90░ left and mirrored|_ 90░ right|90░ right and mirrored|90░ left", "|") If _FileReadAtOffsetHEX ($file, $exif_offset+10, 2) = "4D4D" then $ByteOrder = 1 $size = _FileReadAtOffsetHEX ($file, $exif_offset+2, 2) $exif_offset = $exif_offset + 11 + 9; 9 JFIF header size + 11 - IDF header size, For $ic = 0 To 11 $tag_full = _FileReadAtOffsetHEX($file, $exif_offset + $ic * 12, 12) $id = StringLeft($tag_full, 4) If $ByteOrder Then $id = StringRight($id, 2) & StringLeft($id, 2) Select Case $id = "6987"; Exif IDF offset $idf_offset = _GetNumValue(StringRight($tag_full, 8), $ByteOrder) Case $id = "3201"; DateTime 3201 $exif[0] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "0F01"; Vendor $exif[1] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "1001"; Model $exif[2] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "0E01"; ImageDescription $exif[3] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "9882"; Copyright $exif[4] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "1201"; Orientation $value = _GetNumValue(StringRight($tag_full, 8), $ByteOrder) If $ByteOrder Then $value = BitShift($value, 16) If ($value > 0) and ($value < 9) Then $exif[5] = $orient[$value] Else $exif[5] = "Undefined" Endif EndSelect Next If not ($idf_offset > 0) Then Return($exif) For $ic = 0 To 23 $tag_full = _FileReadAtOffsetHEX ($file, $idf_offset + 15 + $ic * 12, 12) $id = StringLeft($tag_full, 4) If $ByteOrder Then $id = StringRight($id, 2) & StringLeft($id, 2) Select Case $id = "02A0"; Width $exif[6] = _GetNumValue(StringRight($tag_full, 8), $ByteOrder) Case $id = "03A0"; Height $exif[7] = _GetNumValue(StringRight($tag_full, 8), $ByteOrder) Case $id = "0390"; DateTimeOriginal $exif[8] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "0490"; DateTimeDigitized $exif[9] = _ReadValue($file, $tag_full, $ByteOrder) Case $id = "8692"; UserComments $exif[10] = _ReadValue($file, $tag_full, $ByteOrder) EndSelect Next Return($exif) EndFunc Func _ReadValue($file, $tag, $ByteOrder) Local $count = _GetNumValue(StringMid($tag, 9, 8), $ByteOrder) Local $offset = _GetNumValue(StringMid($tag, 17, 8), $ByteOrder) Local $tStr = _FileReadAtOffsetHEX ($file, $offset+13, $count) Local $oStr = "" While StringLen($tStr) > 0 $oStr = $oStr & Chr(Dec(StringLeft($tStr, 2))) $tStr = StringTrimLeft($tStr, 2) WEnd Return($oStr) EndFunc Func _GetNumValue ($input, $ByteOrder) Local $tStr = "" If $ByteOrder then $tStr = $input Else While StringLen($input) > 0 $tStr = $tStr & StringRight($input, 2) $input = StringTrimRight($input, 2) WEnd Endif Return (Dec($tStr)) EndFunc Func _FileReadAtOffsetHEX ($file, $offset, $bytes) Local $tfile = FileOpen($file, 0) Local $tstr = "" FileRead($tfile, $offset-1) For $i = $offset To $offset + $bytes - 1 $tstr = $tstr & Hex(Asc(FileRead($tfile, 1)), 2) Next FileClose($tfile) Return ($tstr) Endfunc Edited August 9, 2004 by Kot Parsix 1 Koda homepage ([s]Outdated Koda homepage[/s]) (Bug Tracker)My Autoit script page ([s]Outdated mirror[/s]) Link to comment Share on other sites More sharing options...
Lazycat Posted August 9, 2004 Author Share Posted August 9, 2004 (edited) Code updated, now UDF works fine with EXIF's have Motorola byte order (for ex. Casio). Also EXIF segment searching is more robust. But it still return wrong info from edited images - I have no idea where the prob lays I'll also try to add more EXIF parameters support Edited August 9, 2004 by Kot Koda homepage ([s]Outdated Koda homepage[/s]) (Bug Tracker)My Autoit script page ([s]Outdated mirror[/s]) Link to comment Share on other sites More sharing options...
dmoniac Posted July 9, 2008 Share Posted July 9, 2008 I have found a bug in the ParseExif function. muttley You use the $file variable but is not defined in the list of parameter of ParseExif function. To fix it, retype function declaration : Func ParseExif($file, $exif_offset) and to call it in the _GetEXIFData function : if $segtype = "E1" then Return(ParseExif($file,$pos)) Link to comment Share on other sites More sharing options...
Lazycat Posted July 10, 2008 Author Share Posted July 10, 2008 dmoniac, this is the really ancient script muttley You can try it's successor _ImageGetInfo (link to site in my sig). Seems, object-based solution was available somewere too. Koda homepage ([s]Outdated Koda homepage[/s]) (Bug Tracker)My Autoit script page ([s]Outdated mirror[/s]) Link to comment Share on other sites More sharing options...
dmoniac Posted July 10, 2008 Share Posted July 10, 2008 dmoniac, this is the really ancient script muttley You can try it's successor _ImageGetInfo (link to site in my sig). Seems, object-based solution was available somewere too.Ok.Thanks Link to comment Share on other sites More sharing options...
joseLB Posted August 30, 2011 Share Posted August 30, 2011 dmoniac, this is the really ancient script You can try it's successor _ImageGetInfo (link to site in my sig). Seems, object-based solution was available somewere too.Hi, Lazy, I was looking your "new" script, but it does not edit or write to the EXIF file. Do you have some clues on that?ThanksJose Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now