Files Delphi

Title: Read picture maketime from digital camera file (JPEG)
Question: How to read the maketime of the picture from the JPEG-file from a digital camera?
Answer:
//----------------------------------------------------------------------
(*
Explanation
===========
Almost every digital camera stores the datetime of the real time camera
clock in the JPG-file when a picture is taken. Unfortunately it is not
documented where. Only the format is documented by Exif.
This simple function first searches for the word: "Exif" in the JPG-
file. The magic word should be found at file offset 6.
If the function has found the magic word, it searches for the datetime,
which should have the following format:
'YYYY:MM:DD' + #32 + 'HH:NN:SS' + #0
See:
wwwde.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf
for details about the Exif 2.2 definition. See page: 28 and: 36 for the
above mentioned datetime definition.
The function ReadExifDate
=========================
This function will return the first occurence of the datetime found in
the JPG-file if the word: Exif is found. Different camera types (of the
same brand!) put the datetime at different offset locations in the JPG-
file... See the listing below:
The function below was tested on the JPEG-files of the following
camera types:
- OLYMPUS C900Z (EUR-type number), D400Z (US-type number of the same
camera). The camera type can be found in the Exif part.
Identical datetimes were found at offset: $114, $246 and $25A
- OLYMPUS X200, D560Z, C350Z. (Datetime "0000:00:00 00:00:00" found in
the file.) The camera type can be found in the Exif part.
Identical datetimes were found at offset: $12A, $3D4 and $3E8
- SONY CYBERSHOT. The camera type can be found in the Exif part. No
additional type number info was found in the file.
Identical datetimes were found at offset: $0D8, $20A, $21E and $314.
- Canon IXUS 300. The camera type can be found in the Exif part. The
Exif part also contains the name of the owner of the camera!
Identical datetimes were found at offset: $0BC, $21A and $22E
*)
//----------------------------------------------------------------------
Function TForm1.ReadExifDate(var sDate : String) : Boolean;
(*
The function returns a True if the JPEG-file has an Exif part and tries
to find the datetime, which will be in sDate.
The function returns a False if no Exif part is found. In that case
sDate will be an empty string
*)
Const
Numbers9 : Set of Char = ['0'..'9'];
Numbers1 : Set of Char = ['0'..'1'];
Numbers3 : Set of Char = ['0'..'3'];
Numbers5 : Set of Char = ['0'..'5'];
MaxItems = $9FF; // Must be enough
Var
f : File of Char;
s : String;
i,j : Integer;
a : Array[0..MaxItems] of Char;
Begin
Result := False; // Init Result
sDate := ''; // Init sDate
OpenDialog1.Filter := 'JPEG files|*.jpg;*.jpeg';
If OpenDialog1.Execute then
Begin
s := ''; // Init s
AssignFile(f,Opendialog1.Filename);
Filemode := 0; // We don't want to write to the file
Reset(f);
// Read the first part of the JPEG-file into an array of char
For I := 0 to MaxItems do
Begin
If not Eof(f) then
Read(f,a[i]); // Add char to the array of char
End;
CloseFile(f);
End;
s := a[6] + a[7] + a[8] + a[9]; // This must be the magic word: "Exif"
If ANSIUppercase(s) = 'EXIF' then // ANSIUppercase is in D5 and higher
Result := True
else
Exit; // If the magic word: "Exif" was not found: ready searching
// No Exif datetime in the file
//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// Extract the datetime if the magic word: "Exif" is found
For I := 10 to MaxItems - 15 do
Begin
If a[i] = ':' then
Begin
s := '';
// Assemble the datetime string
For j := 0 to 18 do
s := s + a[i + j - 4]; // - 4 for "YYYY"
// Check the pattern
// This must not be so thorougly as done below...
If // Check for year number (4 digits)
(s[01] in Numbers9) and (s[02] in Numbers9) and
(s[03] in Numbers9) and (s[04] in Numbers9) and
(s[05] = ':') and
// Check for month number (2 digits)
(s[06] in Numbers1) and (s[07] in Numbers9) and
(s[08] = ':') and
// Check for day number (2 digits)
(s[09] in Numbers3) and (s[10] in Numbers9) and
(s[11] = ' ') and
// Check for hour (2 digits)
(s[12] in Numbers5) and (s[13] in Numbers9) and
(s[14] = ':') and
// Check for minute (2 digits)
(s[15] in Numbers5) and (s[16] in Numbers9) and
(s[17] = ':') and
// Check for second (2 digits)
(s[18] in Numbers5) and (s[19] in Numbers9) then
Begin
// Yes, a datetime is found!!!
sDate := s;
If sDate = '0000:00:00 00:00:00' then
ShowMessage('Illegal datetime found!');
// This I found in one Olympus X200, D560Z, C350Z JPEG-file
Exit; // Ready
End;
End;
End;
End;
//----------------------------------------------------------------------