AutoHotkey Community

It is currently May 25th, 2012, 5:15 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: date picture taken
PostPosted: May 15th, 2007, 2:31 pm 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 3:26 pm 
Offline

Joined: November 27th, 2006, 7:41 am
Posts: 222
Location: Queensland, Australia
using FileGetTime?
http://www.autohotkey.com/docs/commands/FileGetTime.htm


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 3:49 pm 
Offline

Joined: November 28th, 2005, 11:24 am
Posts: 89
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 5:17 pm 
Double post: picture organization
And original proposal was about A_LoopFileTimeCreated, which make more sense (if camera sets it) than A_LoopFileTimeModified...


Report this post
Top
  
Reply with quote  
 Post subject: Re: date picture taken
PostPosted: May 15th, 2007, 5:21 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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.

:)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 5:43 pm 
http://www.houseofroettger.com/00017.JPG

They all are from the same camera. Thanks SKAN[/img]


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 5:49 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
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

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on May 16th, 2007, 9:31 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 15th, 2007, 9:20 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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. :(

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
}


:)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 5th, 2009, 9:37 pm 
Offline

Joined: July 5th, 2009, 9:29 pm
Posts: 3
This code works for me to get the exif date picture taken with ahk only :) (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
}


Report this post
Top
 Profile  
Reply with quote  
PostPosted: January 3rd, 2010, 11:15 pm 
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 6th, 2010, 9:13 pm 
nvm made my own that works


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 12th, 2010, 3:29 pm 
can you share that with us?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 12th, 2010, 8:36 pm 
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.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 12th, 2010, 9:48 pm 
:lol:
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


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: January 12th, 2010, 10:21 pm 
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]


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: 0x150||ISO, alanofoz, Bing [Bot], poserpro, Sambo, tommy and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group