AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

date picture taken

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
bob_C
Guest





PostPosted: Tue May 15, 2007 1:31 pm    Post subject: date picture taken Reply with quote

I am trying to access the "Date Picture Taken" heading in the details view to sort pictures. Not the "Last modified" can someone tell me if this is possible and what the command is.

Like with Last Modified it is.

%A_LoopFileTimeModified%

What is the "Date Picture Taken" version of the above command.

Thanks
Back to top
BETLOG



Joined: 27 Nov 2006
Posts: 222
Location: Queensland, Australia

PostPosted: Tue May 15, 2007 2:26 pm    Post subject: Reply with quote

using FileGetTime?
http://www.autohotkey.com/docs/commands/FileGetTime.htm
Back to top
View user's profile Send private message
Gast (w/ nick)



Joined: 28 Nov 2005
Posts: 83

PostPosted: Tue May 15, 2007 2:49 pm    Post subject: Reply with quote

Once the file is modified, the original data can't be seen by the operating system (to my knowledge)

If your camera stores the date taken in the Exif-Data of the image,
you could look there or google for other exif-reading tools.

http://www.codeproject.com/csharp/exifextractor.asp
Back to top
View user's profile Send private message
Grumpy
Guest





PostPosted: Tue May 15, 2007 4:17 pm    Post subject: Reply with quote

Double post: picture organization
And original proposal was about A_LoopFileTimeCreated, which make more sense (if camera sets it) than A_LoopFileTimeModified...
Back to top
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Tue May 15, 2007 4:21 pm    Post subject: Re: date picture taken Reply with quote

bob_C wrote:
I am trying to access the "Date Picture Taken" heading in the details view to sort pictures.


If all the photos have been taken from the same camera, post a sample image and I can give you a customised binary function that will extract the Exif date from the file.

Smile
Back to top
View user's profile Send private message Send e-mail
bob_c
Guest





PostPosted: Tue May 15, 2007 4:43 pm    Post subject: Reply with quote

http://www.houseofroettger.com/00017.JPG

They all are from the same camera. Thanks SKAN[/img]
Back to top
PhiLho



Joined: 27 Dec 2005
Posts: 6836
Location: France (near Paris)

PostPosted: Tue May 15, 2007 4:49 pm    Post subject: Reply with quote

Found in the forum: JPEG Metainformation
Thanks BoBo the utility finder!
Correct URL: Exiv2 - Exif and IPTC metadata library and tools
Result:
Code:
output = %A_Temp%\$$ExivOutput$$
RunWait %comspec% /c exiv2 -Pnv E:\Documents\Images\Exif_kodak-dc240.jpg > %output%, , Hide
FileRead exifData, %output%
FileDelete  %output%
; DateTimeOriginal             1999:05:25 21:00:09
RegExMatch(exifData, "m)^DateTimeOriginal\s+(.*)$", date)
MsgBox Photo taken at %date1%

I use the old method of redirecting to a file.
You might prefer to use CMDret, StdoutToVar or Std In/Out/Err via COM
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on Wed May 16, 2007 8:31 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Tue May 15, 2007 8:20 pm    Post subject: Reply with quote

Try this code along with copies of some pictures taken in different resolution, You should see a MsgBox for each picture.

Well, I am not sure about my code. If you find it does not work for many photos then I will need a couple of more images. Sad

Code:
SetWorkingDir, %A_ScriptDir%

Loop *.jpg
 {
  ImgTime := Kodak( A_LoopFileLongPath )
  If ! ImgTime
     Continue
  FormatTime, Time, %ImgTime%,MMM,dd yyyy [ hh:mm.ss tt ]
  MsgBox, 0, %A_LoopFileName%, % Time

 }


Kodak( file="" ) {
FileRead, binData, *m2048 %file%
P := &binData,  RV := 0

Loop, 2048                     
  If ( *(P+(A_Index-1)) = 0 )
     DllCall( "RtlFillMemory", UInt, P+(A_Index-1), Int,1, UChar,32 )

IfNotInString, binData, KDK0002IDX4530, Return 0

Loop, Parse, binData, `n
   If ( SubStr(A_LoopField,5,1 ) = ":" AND SubStr(A_LoopField,8,1 ) = ":" )
      {
        StringReplace, RV, A_LoopField, %A_Space%,, All
        StringReplace, RV, RV, :,, All
        RV := SubStr( RV, 1, 14 )
      }
Return RV
}


Smile
Back to top
View user's profile Send private message Send e-mail
hberntsen



Joined: 05 Jul 2009
Posts: 3

PostPosted: Sun Jul 05, 2009 8:37 pm    Post subject: Reply with quote

This code works for me to get the exif date picture taken with ahk only Smile (or are there better alternatives?)
Code:

GetDateTaken(file,bytes=512,tries=10)
{
/*
bench:
1896 jpg files, total 1,68 GB (1.807.804.409 bytes)

tries = 10
512b - 72.640000 seconds
1024b - 76.360000
2048b - 86.844000
3072b - 81.359000
*/
loop,%tries%
{
   bc := bytes * a_index
   ;http://www.autohotkey.com/forum/topic19227.html
   FileGetSize, fs,%file%
   if (fs < bc) ; otherwise, dllcall crashes
      break
   FileRead, binData, *m%bc% %file%
   P := &binData,  RV := 0
   Loop, %bc%                     
     If ( *(P+(A_Index-1)) = 0 )
       DllCall( "RtlFillMemory", UInt, P+(A_Index-1), Int,1, UChar,32 )

   Loop, Parse, binData, `n
   {
      RegExMatch(A_LoopField,"\d\d\d\d:\d\d:\d\d \d\d:\d\d:\d\d", date)
      if date !=
         break
   }
   if date !=
      return substr(date,1,4) . substr(date,6,2) . substr(date,9,2) . substr(date,12,2) . substr(date,15,2) . substr(date,18,2)
}
   return false
}
Back to top
View user's profile Send private message
Denise
Guest





PostPosted: Sun Jan 03, 2010 10:15 pm    Post subject: Why does this kill autohotkey? Reply with quote

Hi I tried doing this and it says autohotkey has encountered a error ?

What am I doing wrong ?

Code:

SetWorkingDir, %A_ScriptDir%

DateTaken:=GetDateTaken("test_pic.JPG",512,10)
msgbox DateTaken %DateTaken%
return





GetDateTaken(file,bytes=512,tries=10)
{
/*
bench:
1896 jpg files, total 1,68 GB (1.807.804.409 bytes)

tries = 10
512b - 72.640000 seconds
1024b - 76.360000
2048b - 86.844000
3072b - 81.359000
*/
loop,%tries%
{
   bc := bytes * a_index
   ;http://www.autohotkey.com/forum/topic19227.html
   FileGetSize, fs,%file%
   if (fs < bc) ; otherwise, dllcall crashes
      break
   FileRead, binData, *m%bc% %file%
   P := &binData,  RV := 0
   Loop, %bc%                     
     If ( *(P+(A_Index-1)) = 0 )
       DllCall( "RtlFillMemory", UInt, P+(A_Index-1), Int,1, UChar,32 )

   Loop, Parse, binData, `n
   {
      RegExMatch(A_LoopField,"\d\d\d\d:\d\d:\d\d \d\d:\d\d:\d\d", date)
      if date !=
         break
   }
   if date !=
      return substr(date,1,4) . substr(date,6,2) . substr(date,9,2) . substr(date,12,2) . substr(date,15,2) . substr(date,18,2)
}
   return false
}


Thanks for helping
Back to top
Denise
Guest





PostPosted: Wed Jan 06, 2010 8:13 pm    Post subject: Reply with quote

nvm made my own that works
Back to top
hank
Guest





PostPosted: Tue Jan 12, 2010 2:29 pm    Post subject: Reply with quote

can you share that with us?
Back to top
Denise
Guest





PostPosted: Tue Jan 12, 2010 7:36 pm    Post subject: Reply with quote

It probally could be better or faster I am open for suggestions.


I did +3K photos on my nas all made with my sony camera spoofing the binairy exif header rewriting the windows timestamps.

All credits go to the makers of the functions


Laszlo BinRead

JaseF and Krogdor Hex2ASCII

hberntsen GetDateTaken

hberntsen for his idea todo it like this without a 3rd party app.


My code will read 512 bytes from byte 200 (offset), I opened a few photos and the best change to get a usable date are within these ranges if exif data header is present.


Main code
Code:

Loop, *.jpg,,1
 {
 
 file = %A_LoopFileFullPath%

Progress, b w500, At work,%A_LoopFileFullPath%, %A_LoopFileFullPath%, %A_LoopFileFullPath%
Progress, 10

res := BinRead(file,data,512,200)
Progress, 10
hexdate := GetDateTaken(data)
Progress, 20
hex := Hex2ASCII(hexdate)
Progress, 30
RegExMatch(hex,"\d\d\d\d:\d\d:\d\d\s\d\d:\d\d:\d\d", date)
Progress, 40
if date =
   {
   Progress, 100
    continue
   }
Progress, 50
StringReplace, hex, hex, :, , All
StringReplace, hex, hex, %A_SPACE%, , All
StringLeft, OutputHex, hex, 14
FileGetTime, OutputVar, %A_LoopFileFullPath%, C
if OutputHex = %OutputVar%
   {
   Progress, 100
    continue
   }
Loop,25
{
bar :=  50+A_index
Progress, %bar%
sleep 1
}
FileSetTime, %Outputhex%, %A_LoopFileFullPath%, M
FileSetTime, %Outputhex%, %A_LoopFileFullPath%, C
FileSetTime, %Outputhex%, %A_LoopFileFullPath%, A
Loop,25
{
bar :=  75+A_index
Progress, %bar%
sleep 1
}
}

exitapp



Used Functions

hberntsen GetDateTaken
Code:




GetDateTaken(data)
{
   Loop, Parse, data, `n
   {
      RegExMatch(A_LoopField,"3\d3\d3\d3\d3a3\d3\d3a3\d3\d203\d3\d3a3\d3\d3a3\d3\d", hexdate)
     if hexdate !=
         break
   }
   if hexdate !=
      return hexdate
}

JaseF and Krogdor Hex2ASCII
Code:

Hex2ASCII(fHexString)
{
  Loop Parse, fHexString
  NewHexString .= A_LoopField (Mod(A_Index,2) ? "" : ",")
  StringTrimRight, NewHexString, NewHexString,1
  Loop, Parse, NewHexString, `,
  ConvString .= Chr("0x" A_LoopField)
Return ConvString
}

Laszlo BinRead
Code:

BinRead(file, ByRef data, n=0, offset=0)
{
   h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
   IfEqual h,-1, SetEnv, ErrorLevel, -1
   IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file

   m = 0                            ; seek to offset
   IfLess offset,0, SetEnv,m,2
   r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
   IfEqual r,0, SetEnv, ErrorLevel, -3
   IfNotEqual ErrorLevel,0, {
      t = %ErrorLevel%              ; save ErrorLevel to be returned
      DllCall("CloseHandle", "Uint", h)
      ErrorLevel = %t%              ; return seek error
      Return 0
   }

   TotalRead = 0
   data =
   IfEqual n,0, SetEnv n,0xffffffff ; almost infinite

   format = %A_FormatInteger%       ; save original integer format
   SetFormat Integer, Hex           ; for converting bytes to hex

   Loop %n%
   {
      result := DllCall("ReadFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Read,"UInt",0)
      if (!result or Read < 1 or ErrorLevel)
         break
      TotalRead += Read             ; count read
      c += 0                        ; convert to hex
      StringTrimLeft c, c, 2        ; remove 0x
      c = 0%c%                      ; pad left with 0
      StringRight c, c, 2           ; always 2 digits
      data = %data%%c%              ; append 2 hex digits
   }

   IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%

   h := DllCall("CloseHandle", "Uint", h)
   IfEqual h,-1, SetEnv, ErrorLevel, -2
   IfNotEqual t,,SetEnv, ErrorLevel, %t%

   SetFormat Integer, %format%      ; restore original format
   Totalread += 0                   ; convert to original format
   Return TotalRead
}





After having all this done I made a script that sorted all .jpg into a yyyy-mm-dd folder.

Note* this will only look at the timestamp not the exif data
Code:

Loop, *.jpg,,1
{
SplashTextOn, 400, 300, File, Current file:`n%A_LoopFileFullPath%

LoopFileTimeModified:=substr(A_LoopFileTimeModified,1,4) . "-" . substr(A_LoopFileTimeModified,5,2) . "-" . substr(A_LoopFileTimeModified,7,2)
if LoopFileTimeModified = %A_LoopFileDir%
continue
IfNotExist, %A_ScriptDir%\%LoopFileTimeModified%
FileCreateDir, %A_ScriptDir%\%LoopFileTimeModified%
FileMove, %A_LoopFileFullPath%, %A_ScriptDir%\%LoopFileTimeModified%,0  ; Move the file without renaming it.
}

 exitapp


Leave me a message when you are using it, Thanks.
Back to top
Denise
Guest





PostPosted: Tue Jan 12, 2010 8:48 pm    Post subject: Reply with quote

Laughing
This is even shorter with all credits to [VxE]

for this code:
http://www.autohotkey.com/forum/post-280307.html#280307

Code:

FileRead, Contents, %A_Desktop%\Test.fst
Loop, % VarSetCapacity( Contents )
{
   byte := NumGet( Contents, A_Index - 1, "Char" )
   TextContents .= 31 < byte && byte < 127 ? Chr(byte) : ""
}
Msgbox %TextContents%


My new main code I think it's the smallest possible ,but I dont think it's faster because of fileread?

Code:


Loop, *.jpg,,1
 {
FileRead, Contents,  *m1024 %A_LoopFileFullPath%

Loop,% VarSetCapacity( Contents )
{
   byte := NumGet( Contents, A_Index - 1, "Char" )
   TextContents .= 31 < byte && byte < 127 ? Chr(byte) : ""
}
   Loop, Parse, TextContents, `n
   {
      RegExMatch(TextContents,"\d\d\d\d:\d\d:\d\d\s\d\d:\d\d:\d\d", date)
     if date !=
         break
   }
if TextContents =
   {
    continue
   }
StringReplace, date, date, :, , All
StringReplace, date, date, %A_SPACE%, , All

FileGetTime, OutputVar, %A_LoopFileFullPath%, C

if date = %OutputVar%
   {
    continue
   }
FileSetTime, %date%, %A_LoopFileFullPath%, M
FileSetTime, %date%, %A_LoopFileFullPath%, C
FileSetTime, %date%, %A_LoopFileFullPath%, A
}
exitapp
Back to top
Denise
Guest





PostPosted: Tue Jan 12, 2010 9:21 pm    Post subject: Reply with quote

edit needed to add TextContents:=
Code:



Loop, *.jpg,,1
 {
FileRead, Contents,  *m1024 %A_LoopFileFullPath%

TextContents:=

Loop,% VarSetCapacity( Contents )
{
   byte := NumGet( Contents, A_Index - 1, "Char" )
   TextContents .= 31 < byte && byte < 127 ? Chr(byte) : ""
}
   Loop, Parse, TextContents, `n
   {
      RegExMatch(TextContents,"\d\d\d\d:\d\d:\d\d\s\d\d:\d\d:\d\d", date)
     if date !=
         break
   }
if TextContents =
   {
    continue
   }
StringReplace, date, date, :, , All
StringReplace, date, date, %A_SPACE%, , All

FileGetTime, OutputVar, %A_LoopFileFullPath%, C

if date = %OutputVar%
   {
    continue
   }
FileSetTime, %date%, %A_LoopFileFullPath%, M
FileSetTime, %date%, %A_LoopFileFullPath%, C
FileSetTime, %date%, %A_LoopFileFullPath%, A
}
exitapp
[/b]
Back to top
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group