How to get Date and Time the picture was taken at? - delphi

I am writing a program in Delphi which should get the date and time of the picture which was taken with photo cam and then it would rename the file to include the date+time it found.
So far i have achieved that by opening file as binary and searching for a special order of bytes. These bytes were then followed by the date and then time. So i've come to a problem. Actually few problems.
Because it reads the file 1 byte after another, reading a file is a slow process. If the date was found, it is usually at the start of file, it doesn't take long, however if 'special byte order' was not found, it will read the whole file. So my method is way too slow.
The special byte order may change in some pictures (i have no idea why) even if it was taken with the same camera. So my program sometimes fails to find the date in the file even though it is there.
Windows explorer has no problems finding date in all of the pictures, so i was thinking maybe there are some kind of special functions which could get me what i need?
How do i get the information i need from the picture so it works with all the formats?
Thanks

I think you only need to look at the EXIF information. http://en.wikipedia.org/wiki/Exif
There are some open source tools which accomplish that, but I don't know of anything Delphi specific. If you're not scared of Java, you can have a look at the source code of this open source project: http://sourceforge.net/projects/jexifviewer/ to see how they evaluate the date field.
You can then optimise your reader, to only look at the relevant area. You might want to keep in mind that the Endianness in Java is different to Delphi.

Jules is right about Exif data; you might want to try this Delphi library:
http://delphihaven.wordpress.com/ccr-exif/

This is an amazing site to view Exif data.
http://regex.info/exif.cgi

If it is a graphic file (as in your case), to open it with a dialog box, place a TOpenPictureDialog component on the form.
Also place the component TLabel, for displaying the date of creation of the file.
In the button's place the following code:
if OpenPictureDialog1.Execute then Label1.Caption := DateTimeToStr(FileDateToDateTime(FileAge(OpenPictureDialog1.FileName));
In order to open jpeg and png files in the code, in the line uses you need to add the name of the two libraries, JPEG, PNGImage.
If you have the full address of your file, you can write the code above instead of the code above:
Label1.Caption := DateTimeToStr(FileDateToDateTime(FileAge('full address to file')));
If you only need the date, without the file creation time, then instead of the DateTimeToStr command, use the DateToStr command.

Related

Delphi xe8 error reading textfile created from Delphi 7 version and vice versa

I try to convert a code from Delphi 7 to delphi xe8 and I cannot find a solution to the following case.
Our old application creates a txt file which first row is like that
±HEADER―ID°N1799―USER_ID°N1―PATH_NAME―R_DATABASE°TC:\DATA―R_SERVER°TTEST_SRV―R_COMPUTER°TMYPC―
Char(―) is chr(175).
We tried to read the already created file from our new application with Delphi xe8 like that:
StrData := TStringList.Create;
StrData.LoadFromFile(sFile);
StrData.Text returns the desired text but chr(175) is replaced with chr(8213).
In order to go on I did the followings:
StrData.LoadFromFile(sFile,TEncoding.ANSI);
StrData.Text := StringReplace(StrData.Text,Chr(8213),Chr(175),[rfReplaceAll]);
What I cannot solve is the opposite case.
I have to create that file from Delphi xe8 so as it would be exactly the same with the one produced from the old delphi 7 application.
At the beginning I used the same code we had:
StrData.SavetoFile(sFile); //returns text but chr(175) is replaced with (?)
Also i tried all encodings with no results.
StrData.SavetoFile(sFile,Ansi);//returns text but chr(175) is replaced with (?) etc.
The same results also when converts the code to TStreamFile or textfile.
base64 encode files
Old one - Correct one (StrData.SavetoFile(sFile)) //Delphi 7
wrFIRUFERVLigJVJRMKwTjE4NjbigJVSSUTCsE4zNjHigJVDU0lURV9JRMKwTjHigJVSU0lURV9JRMKwTjEwMeKAlVNTSVRFX0lEwrBOMeKAlVRSTl9EQVRFwrBENDIzODIuNjA2NzkzOTgxNeKAlVVTRVJfSUTCsE4x4oCVUEFUSF9OQU1FwrBUXFxkZWxwaGkyMDEycjJcQkVORUZJVF9URVNUXFBBX09GRklDRV9WU0xcVFJBTlNGRVJcRVhQT1JU4oCVRklMRV9OQU1FwrBUQU5BRDM2MU0udHh04oCVRklMRV9UWVBFwrBO4oCVUENLX1NFTkRFUsKwVEFkbWlu4oCVUENLX05PVEVTwrBU4oCVX1JWX0lEMcKwTuKAlVNWX0lEwrBO4oCVUlZfSUTCsE7igJVSREJfSUTCsE4xMeKAlVNEQl9JRMKwTjEx4oCVUENLX0NOWFTCsFQwMywxNSw3MiwwMOKAlUtFWUlEwrBUezczRDIwMDU3LTM3NTgtNDlDMi05NTlGLTA4QzYxMDY4NEZGNn3igJVGTF9UWVBFwrBOMuKAlUZMX1NUQVRVU8KwTjDigJVTVEFSVF9EVMKwRDQyMzgyLjYwNjQ5MzA1NTbigJVSX1NUQVJUX0RUwrBE4oCVUl9FTkRfRFTCsETigJVSX1VTRVLCsFTigJVSX1BBVEjCsFTigJVTSVpFX1BDS8KwTuKAlVNJWkVfREFUQcKwTuKAlVNJWkVfQVRDSMKwTuKAlVNJWkVfRE9DU8KwTuKAlURBVEVfSU7CsETigJVSX0RBVEFCQVNFwrBU4oCVUl9TRVJWRVLCsFTigJVSX0NPTVBVVEVSwrBU4oCV
StrData.SavetoFile(sFile,Tencoding.Ansi); & StrData.SavetoFile(sFile); //XE8
wrFIRUFERVI/SUTCsE4xODY3P1JJRMKwTjM2Mj9DU0lURV9JRMKwTjE/UlNJVEVfSUTCsE4xMDE/U1NJVEVfSUTCsE4xP1RSTl9EQVRFwrBENDIzODIuNzA3NzA4MzMzMz9VU0VSX0lEwrBOMT9QQVRIX05BTUXCsFRcXGRlbHBoaTIwMTJyMlxCRU5FRklUX1RFU1RcUEFfT0ZGSUNFX1ZTTFxUUkFOU0ZFUlxFWFBPUlQ/RklMRV9OQU1FwrBUQU5BRDM2Mk0udHh0P0ZJTEVfVFlQRcKwTj9QQ0tfU0VOREVSwrBUQWRtaW4/UENLX05PVEVTwrBOP19SVl9JRDHCsE4/U1ZfSUTCsE4/UlZfSUTCsE4/UkRCX0lEwrBOMTE/U0RCX0lEwrBOMTE/UENLX0NOWFTCsFQwMywxNSw3MiwwMD9LRVlJRMKwVHtGQzM1N0QyNC1EQjRBLTRBOUMtQkE3My0xQ0FBMEVFRDUzOUJ9P0ZMX1RZUEXCsE4yP0ZMX1NUQVRVU8KwTjA/U1RBUlRfRFTCsEQ0MjM4Mi43MDcyNjg1MTg1P1JfU1RBUlRfRFTCsEQ/Ul9FTkRfRFTCsEQ/Ul9VU0VSwrBUP1JfUEFUSMKwVD9TSVpFX1BDS8KwTj9TSVpFX0RBVEHCsE4/U0laRV9BVENIwrBOP1NJWkVfRE9DU8KwTj9EQVRFX0lOwrBEP1JfREFUQUJBU0XCsFQ/Ul9TRVJWRVLCsFQ/Ul9DT01QVVRFUsKwVD8=
StrData.SavetoFile(sFile,Tencoding.UTF8); //XE8
wrFIRUFERVLCr0lEwrBOMTg3MMKvUklEwrBOMzY1wq9DU0lURV9JRMKwTjHCr1JTSVRFX0lEwrBOMTAxwq9TU0lURV9JRMKwTjHCr1RSTl9EQVRFwrBENDIzODIuNzIyODEyNcKvVVNFUl9JRMKwTjHCr1BBVEhfTkFNRcKwVFxcZGVscGhpMjAxMnIyXEJFTkVGSVRfVEVTVFxQQV9PRkZJQ0VfVlNMXFRSQU5TRkVSXEVYUE9SVMKvRklMRV9OQU1FwrBUQU5BRDM2NU0udHh0wq9GSUxFX1RZUEXCsE7Cr1BDS19TRU5ERVLCsFRBZG1pbsKvUENLX05PVEVTwrBOwq9fUlZfSUQxwrBOwq9TVl9JRMKwTsKvUlZfSUTCsE7Cr1JEQl9JRMKwTjExwq9TREJfSUTCsE4xMcKvUENLX0NOWFTCsFQwMywxNSw3MiwwMMKvS0VZSUTCsFR7ODE5REQ0NDQtQzEwQi00MTY1LUFEQjAtQkI2NDAyRjA3NUI4fcKvRkxfVFlQRcKwTjLCr0ZMX1NUQVRVU8KwTjDCr1NUQVJUX0RUwrBENDIzODIuNzIyNTIzMTQ4McKvUl9TVEFSVF9EVMKwRMKvUl9FTkRfRFTCsETCr1JfVVNFUsKwVMKvUl9QQVRIwrBUwq9TSVpFX1BDS8KwTsKvU0laRV9EQVRBwrBOwq9TSVpFX0FUQ0jCsE7Cr1NJWkVfRE9DU8KwTsKvREFURV9JTsKwRMKvUl9EQVRBQkFTRcKwVMKvUl9TRVJWRVLCsFTCr1JfQ09NUFVURVLCsFTCrw==
Any ideas?
The file saved by your Delphi 7 program is UTF-8 encoded. I decoded the base64 that you supplied and look at it in a hex editor. It looks like this:
The first two bytes are C2 B1. That is the UTF-8 encoding for ±. You can check that here: https://mothereff.in/utf-8.
Use LoadFromFile(..., TEncoding.UTF8) to load the file, and SaveToFile(..., TEncoding.UTF8) to save it. That's all you need to do. Note that when you save this way then a BOM will be included in the file. If that is not desired then it possible to omit the BOM, as has been covered here before.
Do note that you must remove the call to StringReplace. That modifies the text and serves no useful purpose. You absolutely do not wish to replace U+2015 ― with U+00AF ¯.
Based on the comments to this answer it seems that you have some Delphi 7 code that produced UTF-8 encoded text which behaves incorrectly when executed by Delphi XE8. That's not surprising due to the change from ANSI to UTF-16. You will need to revisit this code and adapt it appropriately. It's impossible for us to say more given the fact the only you have this code.
It feels very much as though you are trying things almost at random and hoping for a quick fix. That is not productive. You will only make progress with a clear understanding of Unicode, and your program. You will need to step back, slow down, and fill in the gaps in your knowledge.

Xref table - How to recover PDF file if one of the xref trailer has /prev 0 entry

XRef table at offset 666027 has /Prev entry as 0, which seems to be wrong, how to handle such pdfs, how to get the actual /Prev in such cases?
Please look into attached pdf http://www.filedropper.com/hackermonthly-issue-11
Acrobat opens it 'as usual' but then wants to save it on closing. This is an indication it "repaired" the file; probably by enumerating the objects in the file and ignoring the xref tables.
Technically speaking, the file is damaged and there is no right way to "handle" it. Opening then saving it with Acrobat may work for some files, but is it not totally fail-safe; Acrobat still has to guess which objects are still valid and which are not.
The PDF was originally created with Adobe InDesign CS5, which is not known to generate faulty PDFs, and one can assume the tool that was used to add the annotations damaged the file. A cursory glance at the end of the file confirms this: the startxref offset is off by a couple of bytes, and when fixing this with a hex editor, you will only find the previous startxref (for another annotation) is also off by a couple of bytes – at which point I gave up and did not check further. So whatever tool you used to annotate the PDF, don't use it anymore.

How to show Photoshop Action in Forum; save, decrypt, convert .atn file to text?

Briefly, I would like to show a moderately complicated Photoshop action in a forum. Saving the .atn file is easy, but it is encrypted by adobe.
I found a 25,475 line .jsx file which will apparently convert it to XML but is unusable without any usage or documentation
http://ps-scripts.cvs.sourceforge.net/viewvc/ps-scripts/xtools/apps/ActionFileToXML.jsx
What is the easiest way, other than read action word, type word in text editor, to get the 6 inches of action (as seen in Photoshop) into plain text?
GORY DETAILS:
I have a large number of files which I inadvertently damaged by using perfectlyclear on them. It enhances some of the areas but pathologically destroys all darkish areas by converting them to pure black and near zero contrast. When printed, the pictures look like somebody took a black magic marker and redacted large areas. They are damaged beyond use as-is.
The Photoshop fix is to
duplicate layer
select color range, click on a black area, set fuzziness to ~12, range=100%
select expand 4, feather 3
make new mask channel
select backward (original) layer
delete (nukes blackened area under mask)
save as PNG with transparency
This leaves a PNG file with the redacted areas transparent and with feathering around them. By placing the original file beneath it, the original non-blackeded areas are shown.
I would like to document this modest solution in an ImageMagick forum but can not believe how far adobe has gone to lock my action into adobe-only tools. I want to jailbreak this and all of my other actions.
NOTE: There is a one line usage in ActionFileToXML.jsx: "This script reads an ActionFile and converts it to XML" and no documentation of any type. An alert I stumbled upon states that it will only work in CS2/3/4 and I have CS6. It has a 2007 date on it.
I have read that this .JSX is adobe's version of JavaScript and that you run them from inside Illustrator (which I don't have).
I want to figure out how to decrypt my actions and write a useable script:
USAGE: decrypt.atn.to.txt.pl encrypted.atn [-o text_file_name] <enter>
Supply fully qualified path to a .atn" file and it will be deciphered
into a useable .txt file with the same path/basename and a .txt
extension unless you use the -O option which will attempt to write to
the file name you supply.
Perhaps, I could even make a CPAN module?!
Good thing the .JSX writer had the foresight to include 0.0039% documentation or the program would be completely useless! :)
SOLUTION == and STEP by STEP instructions:
The link:
http://ps-scripts.cvs.sourceforge.net/viewvc/ps-scripts/xtools/apps/ActionFileToXML.jsx
points to a gigantic adope extend-script. Reading the file, line 3 has the ~only documentation:
// This script reads an ActionFile and converts it to XML.
The filename already tells you this: ActionFileToXML.jsx
Without wading through 25,000 lines of largely uncommented, 8-year-old code/data/??? it is completely unusable.
What the link poster failed to include was the PACKAGE containing the other 300 files which includes the README.txt, INSTALLATION.txt, /docs, etc.
The PACKAGE supplying context, install, usage, etc can be found at
http://sourceforge.net/projects/ps-scripts/files/xtools/v2.2betas/
How to Decrypt adope's .atn file, step by step:
download README.txt and xtools*.zip from http :// sourceforge.net|projects|ps-scripts|files|xtools|v2.2betas
READ README.txt and unzip zip to any place you like (and REMEMBER where you put it). NOTE: evilnet explorer will by default hide it under some mile long, incredibly ugly file path where you may never find it so use FIREFOX: set tools -> options -> general -> downloads to Always_Ask_Me (or set a reasonable download directory)
Photoshop -> actions, click on action set you want to decipher and click the "arrow box" to the right of actions -> save_actions and put them where you can find them
Photoshop file -> scripts -> browse and navigate to where you stashed ActionFileToXML.jsx and execute. This pops up a GUI as shown at http :// ps-scripts.sourceforge.net|xtools.html
Navigate to where you hid you .atn file, the XML file box will be populated with the same path/file_BASE_name and an XML extension as a default. Adjust name/location to suit
hit PROCESS and in a delightfully brief period (in my case), it was done
Get ready to marvel at the succinct efficiency with which adope stores an action like [select->color_range, localized, fuzziness=14, range=100%] (56 bytes written by hand) in only 3635 bytes of unfathomably labyrinthine XML with no default values left underspecified. It look a lot like IRS regulation fine print! ;)
The main difficulty in trying to make sense of the XML is that it is written in some funky interpreter psycho-code which bears absolutely no resemblance to the keys/clicks you actually used to create it.
One of the steps I was attempting to elucidate was was simply layer (I NEVER ToucheDER) -> layer_mask -> hide_selection. It is diabolically obfuscated as (and I quote):
<ActionItem key="TEXT" expanded="false" enabled="true" withDialog="false" dialogOptions="2" identifier="TEXT" event="make" name="Make" hasDescriptor="true"><ActionDescriptor key="make" count="3"> <DescValueType.CLASSTYPE key="1316429856" id="1316429856" symname="New" sym="Nw " classString="Channel" class="Chnl"/><DescValueType.REFERENCETYPE key="1098129440" id="1098129440" symname="At" sym="At "><ActionReference key="1098129440" id="1098129440" symname="At" sym="At " count="1">
make .. new .. channel .. at .. mask .. hideSelection? Huh?
I had to scratch my head and fiddle around with the Channels panel options before I found the menu solution.
According to the generous and personable developer, Xbytor (who patiently answers emails from agitated would-be users), this XML can be hacked (carefully), translated back into a .ATN file and used by Photoshop. A very powerful possibility.
Brian

Delphi Text Files get NULLS (0's) written to them instead of text

Unfortunately this question may be a bit vague, I have a problem that I am finding difficult to describe, it is intermittent and I cannot reproduce it myself, I am just hoping that someone else has seen something like it before.
My application has quite a lot of text and ini files that get written when it closes down. Typically this would be in response to a Close event, but may also be triggered by a WM_ENDSESSION. Unfortunately at the moment I am not sure if both or only one of these events can result in the problem I am about to describe, because I have been unable to reproduce this problem myself.
The issue I have is that for some users some of the text and ini files end up being written as NULLs. The file sizes end up looking about right, but instead of text, every character is written as a x00. So instead of 500 bytes of regular ASCII text I end up with 500 x00's. I also have an application log file that can sometimes end up with nulls written to it also. However the logging of x00's to the log file does not necessarily correspond to the exact same time as x00's were written to the config files.
For my files I am using TmemIniFile or TstringList which means that ultimately a Tstrings.SaveToFile is being called for all of my config files.
sl:=TstringList.Create;
try
SourceList.GetSpecificSubset(sl);
AppLogLogLine('Commands: Saving Always Available list. List has '+inttostr(sl.Count)+' commands.');
sl.SaveToFile(fn);
finally
sl.Free;
end;
But then I also have instance where I would already have a TstringList in memory and I just call SaveToFile on it. For TmemIniFile the structure would look similar to above. In some instances I may have an outer loop to write multiple lists. Some of those will result in files being written correctly, some will be full of 00's.
EDIT: GetSpecificSubset is simply a function that will populate "sl" with a list of command names. I have "GetAllUsersCommands", "GetHiddenCommands", "GetAlwaysVisibleCommands" etc. Note that my log file also writes this kind of thing, as a check for how big those lists are:
16/10/2013 11:17:49 AM: Commands: Saving Any User list. List has 8 commands.
16/10/2013 11:17:49 AM: Commands: Saving Always Visible list. List has 17 commands.
16/10/2013 11:17:49 AM: Commands: Saving Always Hidden list. List has 2 commands.
I accidentally left the logging line out of the code above. So this log line is the last thing written before calling Tstrings.SaveToFile, and at that point it thinks it has data. Even if somehow each line of text were NULLs, I would still expect to see x13x10 in the files, but that is not happening.
Here's a screen cap from a HEX editor:
EDIT 2: I just realised I left off a very important piece of information. This is only intermittent. It works 99% of the time. When saving files at shutdown it might not even be all files. Even if I have a loop saving multiple similar files, some may work fine and others may fail.

how to read data from dat file?

how to read data from .dat files ?
i just tried like this memo1.lines.loadfromfile('c:\myfile.dat'); but not worked
Note : File type is binary
can any one please help me :)
#radick to show the contents of an binary file in a memo control you must encode o convert the data to valid ASCII characters, to turn it all into text. because you can not load something that is not text into a text control.
you can find a very nice sample from Peter Below in this link.
read a binary file and display the byte values as ASCII?
(source: swissdelphicenter.ch)
Use the TStream descendants from the VCL Classes unit to read binary files.
There are plenty Delphi TStream reading binary files examples you can find using Google.
--jeroen
You might look at this post as they seem to be discussing this very thing.

Resources