ADJT - Version 2.0.
By Gerry Patterson
Last month I described the script adjt, which adjusts timestamps in JPEG
images. I used the script to fix a large number of images that had been
created with a Pentax Optio.
After, which I thought I would not need it again. Our new digital camera
does is very reliable, and not have the problem of losing its internal
clock and, in future, I will be very careful about setting the clock on
the Pentax before taking any more photos with it.
Then I started looking at the large collection of digitised snaps taken with
a Cannon EOS 500. I had thought I would import them and adjust the
DateTimeOriginal with one of the GUI tools.
It soon occurred to me that I could use a Version 2.0 of the adjt script.
Browsing The Archives.
Although Apple's iPhoto shows the timestamp information I was not able to find a tool that allowed me to alter them. The Linux F-spot does allow this. My initial thoughts were that it would be easiest to load the images into F-spot, adjust the timestamps and then export them. I could then load them into the library in iPhoto.
However, further investigation proved that this would be labour intensive and tedious. I could see that it would take a long time to get each batch of photos done.
As in previous experiments with photo cataloguing software, I realised that it was important to get the timestamps right before importing into the library.
Unlike images created with a digital camera, film images that have been digitised do not have a DateTimeOriginal tag. It is either missing or blank. Depending on where you had the film processed, the other tags, CreateDate and ModifyDate, may also be missing or blank. The films that I had were from several different sources. Each of these sources had their own format. Here are some examples:
- Extrafilm. Each disk would have several folders with various
software for Mac and Windows. The images would be stored in these four
folders, called PICTURES/LARGE, PICTURES/MEDIUM, PICTURES/SMALL
and PICTURES/THUMB. Only the large ones are required. Smaller
versions can be shrunk from the large ones.
In the LARGE folder there are a number of photos like this:
-rwxr-xr-x 1 gerry gerry 643852 Nov 13 2000 04_00.JPG -rwxr-xr-x 1 gerry gerry 809518 Nov 13 2000 05_00A.JPG -rwxr-xr-x 1 gerry gerry 663751 Nov 13 2000 06_0.JPG ... -rwxr-xr-x 1 gerry gerry 770428 Nov 13 2000 39_16A.JPG
None of these files would have the internal timestamps set.
FILENAME DateTimeOriginal CreateDate ModifyDate FileModifyDate -------- ------------------- ------------------- ------------------- ------------------- 04_00.JPG 2000:11:13 12:11:40 05_00A.JPG 2000:11:13 12:11:40 06_0.JPG 2000:11:13 12:11:41 ... 39_16A.JPG 2000:11:13 12:11:59
- Kodak. Each disk would have some software
for Windows. The photos would be in a folder called PICTURES like this:
-rwxr-xr-x 1 gerry gerry 407089 Jan 17 2000 004_1A.JPG -rwxr-xr-x 1 gerry gerry 445104 Jan 17 2000 005_2A.JPG ... -rwxr-xr-x 1 gerry gerry 536313 Jan 17 2000 027_24A.JPG
Mac OS X seems to always recognise Kodak as photos. It automatically launches iPhoto and attempts to import the pictures. I usually cancel this immediately. The photos have teimstamps in all tags except DateTimeOriginal.
FILENAME DateTimeOriginal CreateDate ModifyDate FileModifyDate -------- ------------------- ------------------- ------------------- ------------------- 004_1A.JPG 2000:01:17 11:55:32 2000:01:17 11:55:32 2000:01:17 18:57:06 005_2A.JPG 2000:01:17 11:55:32 2000:01:17 11:55:32 2000:01:17 18:57:07 ... 027_24A.JPG 2000:01:17 11:55:32 2000:01:17 11:55:32 2000:01:17 18:57:27
There several other examples in our collection, but most of them are similar.
The photos on each disk are in reverse chronological order, since the Cannon EOS 500 automatically winds the film on fully when the camera back is closed, after which it winds the film back into the canister as each frame is exposed.
It would be possible to set the date with exiftool, but this would involve a lot typing. e.g. if a script was prepared with line for each file as follows:
exiftool -DateTimeOriginal="2000:10:31 12:30:00" 04_00.jpg exiftool -DateTimeOriginal="2000:10:31 12:25:00" 05_00A.jpg ...
Often photographs are taken in blocks. There will be several taken at approximately a one minute interval, and then the next block might occur several days or weeks later.
So I returned to the script that I had written previously and added some improvements.
Interactive Mode.
The first option that I included was an Interactive mode. by using the readline library (in Term::ReadLine), I could make life a lot easier when it came to typing repetitive dates.
For this reason I coded the script so that it would only operate on the DateTimeOriginal tag while in interactive mode.
This would make it much easier to enter dates. Quite often only a portion of a the previous timestamp has changed. With the readline library enabled, it is possible to recall, and edit the previous line with the arrow keys.
In addition to this, I added some code that would automatically add the adjt-adjustment if the enter key was pressed (Empty string). Provided at least one date had been entered then the timestampe would be incremented by the the adjt-adjustment. If this amount was not specified (in interactive mode, as a command line option or in the environment) then it would be set to one minute.
A new version of the script, Version 2.0, can be found at this site. (see the bibliography for details).
In order to use this new version of the script, it is best to have copies of the files in two separate folders. By using a browser on one folder and the adtj command script in another window (on the other folder), it is possible to flick between the GUI and the command line and enter the dates.
Interactive Mode -- Example Session.
The following is an example of a session, in which I process an Extrafilm disk. I put the disk in the drive and copied the files from the LARGE folder into two separate folders, one of them called ~/temp and the other called ~/photo_wrk. This was on a Mac, so I used the Mac Finder to navigate to the temp folder and selected all the files with the Mac-A key. The I opened them all with File->Open. This opened all the images with the Apple Preview application.
In the ~/photo_wrk folder, I start the adjt script, using the -I option (for interactive). The following is the screen output from this session. The underlined sections are system prompts. The responses are in plain (not underlined) text. Comments are on the right hand side in blue. Empty strings have the word Null in the comment column
pgts07:~/photo_wrk gerry$ adjt -I *JPG ADJT Starting in Interactive mode Enter 'help or ?' for help. |
Start interactive mode. | ||
adjt-> set reverse reverse ON |
Reverse the filelist | ||
adjt-> set digitised-date 2000:11:13 12:11:40 digitised-date 2000:11:13 12:11:40 |
Set CreateDate | ||
adjt-> set rename C10011A01 rename C10011A01 |
Rename Skeleton | ||
adjt-> show all Option Value --------------- --------------- adjt-amt "" adjt-direction "" backup "" digitised-date 2000:11:13 12:11:40 done "" files 36, not committed overwrite OFF preserve ON rename C10011A01 reverse ON test OFF |
Check current status before the "roll" command | ||
adjt-> roll Entering interactive batch mode ... FILENAME DateTimeOriginal CreateDate ModifyDate FileModifyDate ---------- ------------------- ------------------- ------------------- ------------------- 39_16A.JPG 2000:11:13 12:11:59 |
Exit interactive setup | ||
39_16A.JPG: 2000:09:10 15:00:00 39_16A.JPG ** 2000:09:10 15:00:00 2000:11:13 12:11:40 => C10011A01.jpg 38_16.JPG 2000:11:13 12:11:59 |
DateTimeOriginal | ||
38_16.JPG: r14 38_16.JPG ** 2000:09:10 15:01:00 2000:11:13 12:11:40 => C10011A02.jpg 37_15A.JPG ** 2000:09:10 15:02:00 2000:11:13 12:11:40 => C10011A03.jpg 36_15.JPG ** 2000:09:10 15:03:00 2000:11:13 12:11:40 => C10011A04.jpg 35_14A.JPG ** 2000:09:10 15:04:00 2000:11:13 12:11:40 => C10011A05.jpg 34_14.JPG ** 2000:09:10 15:05:00 2000:11:13 12:11:40 => C10011A06.jpg 33_13A.JPG ** 2000:09:10 15:06:00 2000:11:13 12:11:40 => C10011A07.jpg 32_13.JPG ** 2000:09:10 15:07:00 2000:11:13 12:11:40 => C10011A08.jpg 31_12A.JPG ** 2000:09:10 15:08:00 2000:11:13 12:11:40 => C10011A09.jpg 30_12.JPG ** 2000:09:10 15:09:00 2000:11:13 12:11:40 => C10011A10.jpg 29_11A.JPG ** 2000:09:10 15:10:00 2000:11:13 12:11:40 => C10011A11.jpg 28_11.JPG ** 2000:09:10 15:11:00 2000:11:13 12:11:40 => C10011A12.jpg 27_10A.JPG ** 2000:09:10 15:12:00 2000:11:13 12:11:40 => C10011A13.jpg 26_10.JPG ** 2000:09:10 15:13:00 2000:11:13 12:11:40 => C10011A14.jpg 25_09A.JPG ** 2000:09:10 15:14:00 2000:11:13 12:11:40 => C10011A15.jpg 24_09.JPG 2000:11:13 12:11:53 |
The next 14 photos are all taken close together, space them at one minute intervals | ||
24_09.JPG: 2000:09:14 18:30:00 24_09.JPG ** 2000:09:14 18:30:00 2000:11:13 12:11:40 => C10011A16.jpg 23_08A.JPG 2000:11:13 12:11:53 |
DateTimeOriginal | ||
23_08A.JPG: 23_08A.JPG ** 2000:09:14 18:31:00 2000:11:13 12:11:40 => C10011A17.jpg 22_08.JPG 2000:11:13 12:11:52 |
Null | ||
22_08.JPG: 22_08.JPG ** 2000:09:14 18:32:00 2000:11:13 12:11:40 => C10011A18.jpg 21_07A.JPG 2000:11:13 12:11:52 |
Null | ||
21_07A.JPG: 21_07A.JPG ** 2000:09:14 18:33:00 2000:11:13 12:11:40 => C10011A19.jpg 20_07.JPG 2000:11:13 12:11:51 |
Null | ||
20_07.JPG: 2000:09:18 18:33:00 20_07.JPG ** 2000:09:18 18:33:00 2000:11:13 12:11:40 => C10011A20.jpg 19_06A.JPG 2000:11:13 12:11:51 |
DateTimeOriginal | ||
19_06A.JPG: 19_06A.JPG ** 2000:09:18 18:34:00 2000:11:13 12:11:40 => C10011A21.jpg 18_06.JPG 2000:11:13 12:11:51 |
Null | ||
18_06.JPG: 2000:09:30 30:34:00 Invalid Date: 2000:09:30 30:34:00 |
** ERROR | ||
18_06.JPG: 2000:09:30 13:34:00 18_06.JPG ** 2000:09:30 13:34:00 2000:11:13 12:11:40 => C10011A22.jpg 17_05A.JPG 2000:11:13 12:11:50 |
DateTimeOriginal | ||
17_05A.JPG: r4 17_05A.JPG ** 2000:09:30 13:35:00 2000:11:13 12:11:40 => C10011A23.jpg 16_05.JPG ** 2000:09:30 13:36:00 2000:11:13 12:11:40 => C10011A24.jpg 15_04A.JPG ** 2000:09:30 13:37:00 2000:11:13 12:11:40 => C10011A25.jpg 14_04.JPG ** 2000:09:30 13:38:00 2000:11:13 12:11:40 => C10011A26.jpg 13_03A.JPG 2000:11:13 12:11:46 |
roll next four photos | ||
13_03A.JPG: 2000:10:01 13:38:00 13_03A.JPG ** 2000:10:01 13:38:00 2000:11:13 12:11:40 => C10011A27.jpg 12_03.JPG 2000:11:13 12:11:46 |
DateTimeOriginal | ||
12_03.JPG: r5 12_03.JPG ** 2000:10:01 13:39:00 2000:11:13 12:11:40 => C10011A28.jpg 11_02A.JPG ** 2000:10:01 13:40:00 2000:11:13 12:11:40 => C10011A29.jpg 10_02.JPG ** 2000:10:01 13:41:00 2000:11:13 12:11:40 => C10011A30.jpg 09_01A.JPG ** 2000:10:01 13:42:00 2000:11:13 12:11:40 => C10011A31.jpg 08_01.JPG ** 2000:10:01 13:43:00 2000:11:13 12:11:40 => C10011A32.jpg 07_0A.JPG 2000:11:13 12:11:43 |
roll next five photos | ||
07_0A.JPG: 2000:10:09 18:43:00 07_0A.JPG ** 2000:10:09 18:43:00 2000:11:13 12:11:40 => C10011A33.jpg 06_0.JPG 2000:11:13 12:11:41 |
DateTimeOriginal | ||
06_0.JPG: 06_0.JPG ** 2000:10:09 18:44:00 2000:11:13 12:11:40 => C10011A34.jpg 05_00A.JPG 2000:11:13 12:11:40 |
Null | ||
05_00A.JPG: 05_00A.JPG ** 2000:10:09 18:45:00 2000:11:13 12:11:40 => C10011A35.jpg 04_00.JPG 2000:11:13 12:11:40 |
Null | ||
04_00.JPG: 04_00.JPG ** 2000:10:09 18:46:00 2000:11:13 12:11:40 => C10011A36.jpg |
Null | ||
pgts07:~/photo_wrk gerry$ |
Finished | ||
SUMMARY.
As can be seen from the details of the above session, I entered a few commands and I entered five dates. However four of these were entered with the readline recall, so I only partially entered them. And I entered a blank line (just press Enter) seven times. I was thus able to input the dates for 36 photos in less than three minutes.
Of course I did have the files open in a Preview window. So I was constantly flicking between the two windows with the Alt-Tab key. In the Preview Window, I had initially navigated to the last photo (because the photos were in reverse sequence). By pressing the up-arrow I would navigate to the next photo. Since I have a Mac Pro with lots of memory, this is almost instantaneous.
Generally, using this technique, I can process a 36 frame roll in 15 minutes. This includes the entire process:
- Copying the files from the disk (to two locations).
- Determining the roll number -- I use CyyymmXNN C = "C" for Cannon, yyy is a 100+ for years >= 2000 and 000 - 099 for years in the previous century mm is the month developed X is a letter to make it unique, NN is a frame number.
- Starting the adjt script in interactive mode, and entering initial setup parameters.
- Importing into the iPhoto library
- Modifying and touching up the photo (where necessary) in the last roll of the library.
- Cleaning up deleting the excess files.
I expect to have worked through my entire collection of digitised film by the end of this month,
One limitation (bug?) with the existing script is that it only operates on dates in the unix epoch (from 2007-01-01 to 2038-01-18. ). A future version will address the problem of dates before the unix epoch. As for dates after the unix epoch -- much cleverer people than yours truly are thinking about this now, dear reader -- if the prophets of doom are correct all unix systems will cease to exist after 2038-01-18. So Steve Ballmer probably has a clock counting down the seconds until that date.
And I discovered something about the Pentax Optio, which makes me think there may be a problem with the firmware. I entered the date of 2008-02-29, using the utilities function, and it confirmed my choice and then turned it into the date 2008-03-01. Intrigued by this behaviour I tried entering in a date of 2008-02-21 23:55:00. And five minutes later the Pentax lost it's tiny mind.
I'd try to get a patch installed in it, except that I have lost the USB cord that connects to it. The USB cord for the Pentax for some reason is difficult to find. I tried the original store that sold it to me and I have tried several other stores but to no avail. For the time being I have been copying the images by removing the memory and reading them with another camera. If I did want to upgrade the firmware I am almost certain that I would need the USB cord. It appearst that I can purchase them online.
BIBLIOGRAPHY:
The following are some links which might prove useful.
ADJT script. This was the original web page about ADJT (first published Feb, 2008). |
|
PGTS ADJT download. This is the latest tarball which should install adjt on most Unix systems. Let me know if it doesn't work for you. |
|
ADJT perl script. This is the source code which goes with this article. |
|
ADJT documentation. This is the manpage which accompanies the script. It has been created with the Ubuntu man2html utility. |