#1 2006-09-12 16:03

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,367

Date and Time from RAW images (CRW, CR2, RAW)

IMPORTANT: Read this topic to the very last post, because updates are posted below!

Many users were asking me to add a support for reading date and time from RAW images. Unfortunately, there is no open-source libraries for Delphi to read these formats (and extract date and time values), and it was too big of a task to write such a library my-self, in my free time. But with the recent release of ReNamer it is finally possible! There are free tools on the Internet that allow reading the date and time from RAW images. Now, ReNamer can re-use their output from within PascalScript rule.

I will give an example of usage for those who needs it:

1) Download a tool called Exiv2 from http://www.exiv2.org/ and unpack it into ReNamer's folder. It is a command-line tool, it will let you extract date and time from RAW images, here is an example:

> exiv2.exe CRW_9367.CRW

Filename        : CRW_9367.CRW
Filesize        : 5637808 Bytes
Camera make     : Canon
Camera model    : Canon EOS 10D
Image timestamp : 2004:03:19 16:13:00
Image number    : 193-9367
Exposure time   : 1/1024 s

...........................

2) Get your hands on the latest version of ReNamer, and add a PascalScript rule with this code:

const
  EXIV = 'exiv2.exe';
  TIME_STAMP_LINE = 5;

var
  Date, Command, Output: string;
  Lines: TStringsArray;

function ExtractDate(const Text: string): string;
var
  I: Integer;
  Started: Boolean;
begin
  Started := False;
  for I:=1 to Length(Text) do
    if (Text[i] >= '0') and (Text[i] <= '9') then
      begin
      Result := Result + Text[i];
      Started := True;
      end
    else if (Text[i] = ':') and Started then
      Result := Result + '-'
    else if (Text[i] = ' ') and Started then
      Result := Result + ' ';
end;

begin
  Command := '"'+EXIV+'" "'+FilePath+'"';
  ExecConsoleApp(Command, Output);
  Lines := WideSplitString(Output, #13#10);
  if (WideArrayLength(Lines) >= TIME_STAMP_LINE) then
    FileName := ExtractDate(Lines[TIME_STAMP_LINE-1]) +
      WideExtractFileExt(FileName);
end.

3) Drag over your RAW images to ReNamer, Preview, and Rename big_smile

P.S. New name for a sample file "CRW_9367.CRW" will be "2004-03-19 16-13-00.CRW", and you can twick it further from here... good luck!

P.P.S. That was done with Exiv2 v0.10 downloaded on 12 of September 2006 and ReNamer v4.15, minor modifications might be required as both of these tools update.

Offline

#2 2006-11-02 20:08

madeinlisboa
Member
Registered: 2006-06-22
Posts: 7

Re: Date and Time from RAW images (CRW, CR2, RAW)

Here it is the revised code. I've made some changes and customized the return string with constants. Give it a try:

const
  EXIV = 'exiv2.exe';
  DATETIMESTRING = 'Image timestamp';
  SEPARATORDATE = '-';
  SEPARATORTIME = '.';
  SEPARATORDATETIME = '_';

var
  Command, Output: string;
  Lines: TStringsArray;

function ExtractDate(const Lines: TStringsArray; FilePath: String): string;
var I, Start : Integer;
    DateAndTime : TStringsArray;

begin
  for I := 0 to WideArrayLength(Lines) - 1 do
  begin
     if (WideCopy(Lines[i], 1, WideLength(DATETIMESTRING)) = DATETIMESTRING) then
     begin
        Start := WidePos(': ', Lines[i]) + 2;

        DateAndTime := WideSplitString(WideCopy(Lines[i], Start, 19), ':');
        Result := DateAndTime[0] + SEPARATORDATE
                  + DateAndTime[1] + SEPARATORDATE
                  + DateAndTime[2] + SEPARATORTIME
                  + DateAndTime[3] + SEPARATORTIME
                  + DateAndTime[4];

        DateAndTime := WideSplitString(Result, ' ');
        Result := DateAndTime[0] + SEPARATORDATETIME + DateAndTime[1] + WideExtractFileExt(FileName);

        exit;
     end
  end;

  Result := Filename;
end;

begin
  Command := '"'+EXIV+'" "'+FilePath+'"';
  ExecConsoleApp(Command, Output);
  Lines := WideSplitString(Output, #13#10);
  FileName := ExtractDate(Lines, FilePath);
end.

This could only be possible with this utility. Now I can rename almost 2000 NEF files in a snap. Thank you Denis!
Carlos

Last edited by madeinlisboa (2006-11-08 13:53)

Offline

#3 2006-11-03 18:11

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,367

Re: Date and Time from RAW images (CRW, CR2, RAW)

Carlos,

As I said in my original post: "minor modifications might be required as both of these tools update". That's what probably happened. The Exiv2 tool got updated, and image timestamp line from the output has been moved from line 5 to line 9 (according to what I see from your modifications). I don't think there was any need for major modifications, you could have just changed TIME_STAMP_LINE constant to 9, and it should've worked smile

Unfortunately I don't have RAW files anymore, to perform the tests and support my guess...

Offline

#4 2006-11-06 17:18

madeinlisboa
Member
Registered: 2006-06-22
Posts: 7

Re: Date and Time from RAW images (CRW, CR2, RAW)

It didn't change to line 9. I was getting warnings in the output and that shifted the date several rows down, but it doesn't mean it will happen with everybody. I only increased the number to make sure enough data was retrieved from the file. The other small patches were included only to make the new filename more customized and to find the exact place of the date and time, thus making the script flexible for future versions.

Cheers wink

Carlos

Offline

#5 2006-11-06 20:05

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,367

Re: Date and Time from RAW images (CRW, CR2, RAW)

It probably would've been better to detect the "Image timestamp" line (like you did), without binding it to some particular line number (like I did). So good job! Did it work for you after all? smile

Offline

#6 2006-11-08 13:39

madeinlisboa
Member
Registered: 2006-06-22
Posts: 7

Re: Date and Time from RAW images (CRW, CR2, RAW)

May be I should have renamed the constant. It is there only to make sure enough lines are retrieved from the output. Perhaps it is better to delete it though. The string verification is enough.
It is working like a charm, thanks to your wonderful utility wink

ps: I changed the code. it's simpler and it works!

Last edited by madeinlisboa (2006-11-08 13:46)

Offline

#7 2006-11-11 15:30

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,367

Re: Date and Time from RAW images (CRW, CR2, RAW)

I found few RAW images, and decided to improve this script! It is optimized and has a better error handling, and now you can also define the output format for the datetime using DATETIMEFORMAT constant! big_smile

Note: you will need the latest dev version, with few new pascalscript functions: ReNamerBeta.zip

const
  EXIV = 'exiv2.exe';
  DATETIMESTRING = 'Image timestamp';
  DATETIMEFORMAT = 'yyyy-mm-dd hh.nn.ss';

function TryExtractDate(const Output: WideString; var DateTime: TDateTime): Boolean;
var
  Lines: TStringsArray;
  I, Start, Position: Integer;
  DateAndTime: String;
  Parts: TStringsArray;
  Date, Time: TDateTime;
  Year, Month, Day, Hour, Min, Sec: Integer;
begin
  Result := False;
  Lines := WideSplitString(Output, #13#10);
  for I := 0 to WideArrayLength(Lines)-1 do
  begin
    Position := WideTextPos(DATETIMESTRING, Lines[i]);
    if Position > 0 then
    begin
      Position := Position + WideLength(DATETIMESTRING);
      DateAndTime := WideCopy(Lines[i], Position, WideLength(Lines[i]));
      DateAndTime := WideTrim(WideReplaceStr(DateAndTime, ':', ' '));
      Parts := WideSplitString(DateAndTime, ' ');
      if WideArrayLength(Parts) = 6 then
      begin
        Year := StrToIntDef(Parts[0], -1);
        Month := StrToIntDef(Parts[1], -1);
        Day := StrToIntDef(Parts[2], -1);
        Hour := StrToIntDef(Parts[3], -1);
        Min := StrToIntDef(Parts[4], -1);
        Sec := StrToIntDef(Parts[5], -1);
        if (Year>0) and (Month>0) and (Day>0) and
           (Hour>=0) and (Min>=0) and (Sec>=0) then
        if TryEncodeDate(Year, Month, Day, Date) then
        if TryEncodeTime(Hour, Min, Sec, 0, Time) then
        begin
          DateTime := Date + Time;
          Result := True;
        end;
      end;
    end
  end;
end;

var
  Command, Output: string;
  DateTime: TDateTime;

begin
  Command := '"'+EXIV+'" "'+FilePath+'"';
  ExecConsoleApp(Command, Output);
  if TryExtractDate(Output, DateTime) then
    FileName := FormatDateTime(DATETIMEFORMAT, DateTime);
end.

Offline

#8 2007-05-02 17:31

tiagomelo
Member
Registered: 2007-05-02
Posts: 3

Re: Date and Time from RAW images (CRW, CR2, RAW)

Revival of this topic....


Actually the script gives the error: Unknow function WideArrayLength();

Should i replace this for length()?

Tiago

Offline

#9 2007-05-02 17:42

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,367

Re: Date and Time from RAW images (CRW, CR2, RAW)

Yes, good man!

You need to replace WideArrayLength() with Length().

Offline

#10 2007-05-02 18:13

tiagomelo
Member
Registered: 2007-05-02
Posts: 3

Re: Date and Time from RAW images (CRW, CR2, RAW)

den4b wrote:

Yes, good man!

You need to replace WideArrayLength() with Length().

Thanks smile

Another quick question, in the line:

  DATETIMEFORMAT = 'yyyy-mm-dd hh.nn.ss';

There some way that he can read the format defined in settings?

Offline

Board footer

Powered by FluxBB