Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to output date created and date modified?
#1
Hi,
I want to output the properties date created and date modified of a jpg file and I used the script below:

DateTime t
FileGetAttributes("$desktop$\test\1.jpg" 0 t); err out _error.description; ret
t.UtcToLocal;
str st=t.ToStr(4)
out "created=%s modified=%s" st

However, the output does not display the accurate date in which the image was created neither displays any difference between date created and date modified.

Could someone tell what is wrong in the script above?

Thank you,
Emerson
#2
the reason your output is the same is your using the same variable for both created and modified

this is more what your after
Code:
Copy      Help
DateTime tc tm
FileGetAttributes("$desktop$\test\1.jpg" 0 tm tc); err out _error.description; ret
tm.UtcToLocal; tc.UtcToLocal;str stm=tm.ToStr(4);str stc=tc.ToStr(4)
out "created=%s modified=%s" stc stm

on another note if the image has metadata you can get the actual date and time the image was taken using this 

Function GetDateTaken
Code:
Copy      Help
str path.expandpath("$desktop$\test\1.jpg")
str R=CsFunc("" path)
if(R !="No MetaData found")
,DateTime dt
,ARRAY(str) arr
,int i nt
,nt=tok(R arr -1 " ")
,_s=arr[0]
,_s.findreplace(":" "/")
,_s+ F" {arr[1]}"
,dt.FromStr(_s)
,out dt.ToStr
else
,out R
#ret
using System;
using System.Drawing.Imaging;
using System.Drawing;
using System.Text;
public class Example
{
,public static string StaticFunc(string s)
,{
,,// Add reference => Assemblies => Framework => System.Drawing
;;;;;;;;// Set the path to your photo file.
,,var path = @s;
,,var image = new Bitmap(path);
;;;;;;;;// Get PropertyItems
,,var propItems = image.PropertyItems;
;;;;;;;// Remove encoding object
,,var encodings = new ASCIIEncoding();
,,string datetime = "";
;;;;;;;// Display
,,int count = 0;
,,foreach (var propItem in propItems)
,,{
,,,// The values below come from http://msdn.microsoft.com/en-us/library/xddt0dz7(v=vs.110).aspx
;;;;;;;;;;;;// Find al values available with Console.WriteLine(propItem.Id.ToString("x"));
,,,if (propItem.Id.ToString("x").Equals("9003")) //ExifDTOriginal
,,,{
,,,,count = 1;
,,,,datetime = encodings.GetString(propItem.Value);
,,,}
,,}
,,if (count == 0)
,,{
,,,return "No MetaData found";
,,}
,,else
,,{
,,,return datetime;
,,}
,}
}
#3
found this in the forum later


Function get_file_extended_properties1
Code:
Copy      Help
;Gets only specified columns
out
str folder="$desktop$\test"
folder.expandpath
str filename="1.jpg"
str getColumns="Date taken"

Shell32.Shell x._create
Shell32.Folder f=x.NameSpace(folder)
;get column names
ARRAY(str) columns
int i
for(i 0 1000000) _s=f.GetDetailsOf(0 i); if(_s.len) columns[]=_s; else break
;for(i 0 columns.len) out columns[i];;uncomment to see all column names

;find indices of columns specified in getColumns
ARRAY(int) colIndices
foreach _s getColumns
,for(i 0 columns.len) if(_s=columns[i]) colIndices[]=i; break

;display data of specified columns of the file
Shell32.FolderItem k=f.ParseName(filename)
str name=k.Name
for i 0 colIndices.len
,int j=colIndices[i]
,_s=f.GetDetailsOf(k j)
,out F"{columns[j]}={_s}"


topic with more functions starts 
http://www.quickmacros.com/forum/showthr...7#pid25547
#4
Hi Kevin, thank you so much again for your help. I really appreciate your attention.

The "Date Taken" from the last code is the only date that I was looking for.
Every time that I download the files from the memory card, it is assigned that specific date and time as "date created"
In other words, your first code is wonderful but the information retrieved was wrong because it was not the really Date Taken. Now that problem is solved.

Brief question: The time retrieved in your first code  was given as hh:mmConfuseds, the last code however, display only hh:mm. Do you know what needs to be changed in the last code to display the full date and time?

Thank you again
Emerson
#5
use Function GetDateTaken

and change line

out dt.ToStr

to

out dt.ToStr(4)
#6
Hi Kevin, you rock, yes, that fixed the problem.
Now I obtain the real date and time when the photo was shot.
I used out dt.ToStr(8) to display the miliseconds.

Have a great evening
Emerson
#7
Hi Kevin,
hopefully this is a brief question:

Do you know how to get a list containing DateTaken from all the files in a folder?

I combined the lines below:

int i
ARRAY(str) a
GetFilesInFolder a "$Desktop$\TEST\" ""
a.sort(8)
for i 0 a.len
    out a[i]

with your function that display the DateTaken

and changed the line below

from
str path.expandpath("$desktop$\test\25.jpg")
to
str path.expandpath("a[i]")

I don't know what is going on, but it returns the following error:


Error (RT) in <open ":1590: /144">Macro2:  0x80131500,
    Parameter is not valid.
    at Example.StaticFunc(String s).    <help #IDP_ERR>?

Do you know what can be going wrong?
Thank you
Emerson
#8
i think 
str path.expandpath(a[i])
#9
yes redbull is correct

here is a modified version of that function with more error handling
Function GetDateTaken2
Code:
Copy      Help
out
int i ii nt
ARRAY(str) a
GetFilesInFolder a "$Desktop$\TEST\" ""
a.sort(8)
for ii 0 a.len
,Dir d.dir(a[ii])
,if(d.FileSize > 0);;error handing to make sure file is not empty(if we try to access empty file, the function will error and end)
,,str path=d.FullPath
,,out path;;comment out or remove this line .Only here to show filename and path
,,str R=CsFunc("" path)
,,if(R !="No MetaData found")
,,,DateTime dt
,,,ARRAY(str) arr
,,,nt=tok(R arr -1 " ")
,,,_s=arr[0]
,,,_s.findreplace(":" "/")
,,,_s+ F" {arr[1]}"
,,,dt.FromStr(_s)
,,,out dt.ToStr(4)
,,else
,,,out R
#ret
using System;
using System.Drawing.Imaging;
using System.Drawing;
using System.Text;
public class Example
{
,public static string StaticFunc(string s)
,{
;;;;;;;;// Set the path to your photo file.
,,var path = @s;
,,var image = new Bitmap(path);
;;;;;;;;// Get PropertyItems
,,var propItems = image.PropertyItems;
;;;;;;;// Remove encoding object
,,var encodings = new ASCIIEncoding();
,,string datetime = "";
;;;;;;;// Display
,,int count = 0;
,,foreach (var propItem in propItems)
,,{
,,,// The values below come from http://msdn.microsoft.com/en-us/library/xddt0dz7(v=vs.110).aspx
,,,if (propItem.Id.ToString("x").Equals("9003")) //ExifDTOriginal
,,,{
,,,,count = 1;
,,,,datetime = encodings.GetString(propItem.Value);
,,,}
,,}
,,if (count == 0)
,,{
,,,return "No MetaData found";
,,}
,,else
,,{
,,,return datetime;
,,}
,}
}
#10
Hi Kevin and Redbull, thank you for your time.
The correction works well.

Now, after 36 files it returns a error related to the memory, please see below:

Error (RT) in <open ":1: /364">Macro1:  0x80131500,
    Out of memory.
    at Example.StaticFunc(String s).
#11
I am so sorry somehow i forgot to add the release of resources to the code.

Function GetDateTaken2
Code:
Copy      Help
out
int i ii nt
ARRAY(str) a
GetFilesInFolder a "$Desktop$\TEST\" ""
a.sort(8)
for ii 0 a.len
,Dir d.dir(a[ii])
,if(d.FileSize > 0);;error handing to make sure file is not empty(if we try to access empty file, the function will error and end)
,,str path=d.FullPath
,,out path;;comment out or remove this line .Only here to show filename and path
,,str R=CsFunc("" path)
,,if(R !="No MetaData found")
,,,DateTime dt
,,,ARRAY(str) arr
,,,nt=tok(R arr -1 " ")
,,,_s=arr[0]
,,,_s.findreplace(":" "/")
,,,_s+ F" {arr[1]}"
,,,dt.FromStr(_s)
,,,out dt.ToStr(4)
,,else
,,,out R
#ret
using System;
using System.Drawing.Imaging;
using System.Drawing;
using System.Text;
public class Example
{
,public static string StaticFunc(string s)
,{
;;;;;;;;// Set the path to your photo file.
,,var path = @s;
,,var image = new Bitmap(path);
;;;;;;;;// Get PropertyItems
,,var propItems = image.PropertyItems;
;;;;;;;// Remove encoding object
,,var encodings = new ASCIIEncoding();
,,string datetime = "";
;;;;;;;// Display
,,int count = 0;
,,foreach (var propItem in propItems)
,,{
,,,// The values below come from http://msdn.microsoft.com/en-us/library/xddt0dz7(v=vs.110).aspx
,,,if (propItem.Id.ToString("x").Equals("9003")) //ExifDTOriginal
,,,{
,,,,count = 1;
,,,,datetime = encodings.GetString(propItem.Value);
,,,}
,,}
,,if (count == 0)
,,{
,,,image.Dispose();
,,,return "No MetaData found";
,,}
,,else
,,{
,,,image.Dispose();
,,,return datetime;
,,}
,}
}
#12
Thank you Kevin,
now the problem is completely finished.

At the end I also changed

from
out dt.ToStr(4)
to
out dt.ToStr(10)
to display only the time as hh:mmConfuseds.ms, the milisecond is an important information for me.

Below I write what all the script above is good for:
INTRODUCTION:
I have a GOPRO camera shooting photos at three independent positions at every 20 seconds.
A step motor is rotating to three specific location with the same time of every 20 seconds.
In principle, if the arduino control of the step motor and the time lapse from GOPRO are 100% correct, the synchronization should not be a problem.
But in reality, they are not, any 0.1 second delay between motor and GOPRO lead to a big difference over long term.

SOLUTION:
Collect the time taken from GOPRO (SCRIPT ABOVE) and plot a chart to see how GOPRO is running, then I adjust the wait time in arduino to synchronize with GOPRO as good as possible.

Thank you again for all your time and patience.
Emerson
#13
 Emerson
I redid the function this version is a lot faster

Function GetDateTaken 
Code:
Copy      Help
out
int i
ARRAY(str) a
GetFilesInFolder a "$Desktop$\TEST\" ""
a.sort(8)
for i 0 a.len
,Dir d.dir(a[i])
,if(d.FileSize > 0);;error handing to make sure file is not empty(if we try to access empty file, the function will error and end)
,,out d.FileName
,,str R=CsFunc("" d.FullPath)
,,if(R !="No MetaData Found")
,,,DateTime dt
,,,dt.FromStr(R)
,,,out dt.ToStr(4)
,,else
,,,out R
#ret
using System;
using System.Drawing.Imaging;
using System.Drawing;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
public class Example
{
,private static Regex r = new Regex(":");
;;;;//retrieves the date taken without loading the whole image
,public static string GetDateTakenFromImage(string path)
,{
,,using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
,,using (Image myImage = Image.FromStream(fs, false, false))
,,{
,,,PropertyItem propItem = null;
,,,try
,,,{
,,,,propItem = myImage.GetPropertyItem(0x9003);
,,,}
,,,catch { }
,,,if (propItem != null)
,,,{
,,,,string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
,,,,return dateTaken;
,,,}
,,,else
,,,,return "No MetaData Found";
,,}
,}
}
#14
Hi Kevin,

FANTASTIC!!!

It is as fast as a formel1 race, incredible.

And it makes total sense to speed up the process, in particular if the number of images increases in the future.

It was running for 4 minutes and 56 seconds to process 4320 images with the former code.
With the current update it runs only 7 seconds to process the same amount of images above.

Thus, the current code makes it 42 faster than before (296/7=42).
Congratulations Kevin, very nice improvement.

I wish you a wonderful weekend
Emerson


Forum Jump:


Users browsing this thread: 1 Guest(s)