Help with speeding up ExifTool

Started by mball, May 16, 2012, 10:18:38 AM

Previous topic - Next topic

Phil Harvey

Your command should be:

exiftool -@ Exif.args -fast2 -G -t -m -q -Exif:DateTimeOriginal -Xmp:Subject

(you forgot the -@, and I forgot to mention that you don't need -common_args either if you're not using -execute.)

Then, parse the stdout from this command.  Lines beginning with "======== FILENAME\n" mark the start of the information from each file.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

mball

Quote from: mball on May 16, 2012, 12:26:08 PM
Thanks for that, its much clearer now. I do know all the filenames beforehand so would I just create the args file with a filename on each line and then run exiftool with the arguments and point to the arg file, i.e.

exiftool -@ /temp/my.args -common_args -fast2 -G -t -m -q

Phil
I am really struggling to get this working, I have created the arg file which contains all the pictures to process but my app just does not complete and just stays open. I am not sure if you can help on this because its probably not an exiftool issue but you may be able to point me in the right direction.

I am sure its the way I am calling exiftool, on debugging this there process is reporting errors

My code is:
            string sArguments = @" - @ Exif.args -fast2 -xmp:subject ";
                Process oP = new Process();
                oP.EnableRaisingEvents = false;
                oP.StartInfo.CreateNoWindow = true;
                oP.StartInfo.LoadUserProfile = false;
                oP.StartInfo.RedirectStandardError = false;
                oP.StartInfo.RedirectStandardOutput = true;
                oP.StartInfo.RedirectStandardInput = true;
                oP.StartInfo.StandardErrorEncoding = null;
                oP.StartInfo.StandardOutputEncoding = Encoding.UTF8;
                oP.StartInfo.UseShellExecute = false;
                oP.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                oP.StartInfo.FileName = @"exiftool.exe";
                oP.StartInfo.Arguments = sArguments;
                /// Translate file names to 8.3
                var files8dot3 = files.Select(x => new { FileName = x, ShortName = GetShortPathName(x) }).ToArray();

                /// Pass all file names in an arg file which is piped to the process (no temporary file)
                string sArgfile = String.Join("\r\n", files8dot3.Select(x => x.ShortName).ToArray());
                FileStream fs = new FileStream(path+@"\Exif.args", FileMode.OpenOrCreate, FileAccess.Write);
           
                byte[] data = Encoding.UTF8.GetBytes(sArgfile);
                fs.Write(data, 0, data.Length);
                fs.Close();
                oP.Start();

                oP.WaitForExit();
                // this is where I would parse the output

Phil Harvey

I always suggest getting something simple working before trying something complicated.

Instead of your complicated command, see if you can get this working first:

exiftool -echo test

Exiftool should just print "test" and exit.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

mball

I have it working now thanks, just having problems parsing the results but getting there

mball

Quote from: mball on May 18, 2012, 11:44:25 AM
I have it working now thanks, just having problems parsing the results but getting there

How should I be parsing, I am calling the exiftool on a command process from windows program, then I loop through my files and add an entry into the args file, then try to parse that before moving on to next file. Its only getting the tags for the first file
Start Process
Loop
   Write filename to args file
   Wait for process to exit
   parse standardout
EndLoop

Phil Harvey

I thought you were writing all of the file names to the args file before calling exiftool -- processing all files in the single call:

Loop
  Write filename to args file
EndLoop
call exiftool
parse standardout
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

mball

My problem with that approach is how do I match my images with the parsed exif data.

Phil Harvey

As I mentioned before: Lines beginning with "======== FILENAME\n" mark the start of the information from each file.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

mball

Ok writing all the filenames to the arg file then calling the process result in the following

where oP is the process in c# using c# to parse the standardoutput stream
output = oP.StandardOutput.ReadLine();

The line for the first file is
XMP        Subject        Yorkshire Dales, Settle

The exiftool arguments are  -@ Exif.args -fast2 -G -t -m -q -Xmp:Subject

Using this method I can interate through the standardoutput stream line by line and get the above results but I cant match this to a filename

Phil Harvey

Looking back, I see you're using the -q option, which suppresses these informational messages.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

mball

I have been playing a bit and changed the output format to csv, this gives me the filename and the subject tags which is good but I am still having problems matching the filenames, not sure why this happens, perhaps you might know.

Arg file contains filename like this
E:\2008_04_12_Settle_Walk\2008 04 12_Settle Walk_0001.JPG

but the result from exiftool is
E:/2008_04_12_Settle_Walk/2008 04 12_Settle Walk_0001.JPG

The slashes are a different way round

mball

Quote from: mball on May 19, 2012, 09:21:04 AM
I have been playing a bit and changed the output format to csv, this gives me the filename and the subject tags which is good but I am still having problems matching the filenames, not sure why this happens, perhaps you might know.

Arg file contains filename like this
E:\2008_04_12_Settle_Walk\2008 04 12_Settle Walk_0001.JPG

but the result from exiftool is
E:/2008_04_12_Settle_Walk/2008 04 12_Settle Walk_0001.JPG

The slashes are a different way round

Ok I sorted it by doing a replace of / with \
I hope its all ok now, seems to be doing what I want. thanks all for your help

Phil Harvey

Yes.  ExifTool expects "/" as a directory separator, and will change "\" to "/" as you have discovered.

I wouldn't recommend -csv if you have a large number of files, since it buffers all information in memory before returning (this is mentioned in the -csv documentation and the performance tips).  Instead, look at -T, -j, -php or -X.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

kemsky

Hi,
is unicode supported in this mode?

Phil Harvey

Do you mean Unicode file names?  These are always a problem with Windows, but fine on any other system.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).