ExifTool Forum

ExifTool => The "exiftool" Application => Topic started by: busywait on December 07, 2017, 07:59:28 AM

Title: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 07, 2017, 07:59:28 AM
Hi, I'm extracting preview images from camera raw files.

There's a working example here:
https://exiftool.org/exiftool_pod.html#COPYING-EXAMPLES (https://exiftool.org/exiftool_pod.html#COPYING-EXAMPLES)

exiftool -if '$jpgfromraw' -b -jpgfromraw -w %d%f_%ue.jpg -execute -if '$previewimage' -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR
QuoteExtract JpgFromRaw or PreviewImage from all but JPG files in DIR, saving them with file names like image_EXT.jpg, then add all meta information from the original files to the extracted images. Here, the command line is broken into three sections (separated by -execute options), and each is executed as if it were a separate command. The -common_args option causes the --ext jpg DIR arguments to be applied to all three commands, and the -srcfile option allows the extracted JPG image to be the source file for the third command (whereas the RAW files are the source files for the other two commands).

While it works, can anyone tell me what the point of the "-if" conditions is? Surely the files will only be created if the respective JpegFromRaw or PreviewImage attributes exist anyway?

Is there anything in that example command that avoids extraction being attempted twice? I think that this simpler version is equivalent:
exiftool -b -jpgfromraw -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR

Edit: I was wrong (nearly right?) see Phil's response below.
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 07, 2017, 09:01:47 AM
Good point.  I don't know why I added these -if conditions.  I will remove them from this example, so it will be:

exiftool -b -jpgfromraw -w %d%f_%ue.jpg -execute -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR

Thanks for pointing this out.

While the -if options are not necessary, the images still need to be extracted in separate commands.  Your command will write both into the same file if they both exist.

- Phil

Edit:  Or this could be done to avoid a warning message if both exist:

exiftool -b -jpgfromraw -w %d%f_%ue.jpg -execute -if 'not $jpgfromraw' -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR

Edit2: The way to combine the first 2 commands into 1 is to use a user-defined Composite tag like the "BigImage" tag in the example config file

exiftool -config example.config -b -bigimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 07, 2017, 09:19:30 AM
Thank you Phil,

Your revised option looks best, I like to avoid getting warnings :)

Sorry to follow up with more questions:

Is each set of "execute" options guaranteed to run in left to right order?

Is PreviewImage always a jpg format image?

Is JpgFromRaw always "better" than PreviewImage? (Perhaps bigger, or more recently   edited)? My own raw files always have a PreviewImage, but never a JpgFromRaw.

Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 07, 2017, 09:59:49 AM
Quote from: busywait on December 07, 2017, 09:19:30 AM
Is each set of "execute" options guaranteed to run in left to right order?

Yes.

QuoteIs PreviewImage always a jpg format image?

Yes.

QuoteIs JpgFromRaw always "better" than PreviewImage?

It should be bigger if it exists, but I won't guarantee that.  But the BigImage tag takes the biggest one.

- Phil
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 07, 2017, 11:38:55 AM
Quote from: Phil Harvey on December 07, 2017, 09:01:47 AM
Edit2: The way to combine the first 2 commands into 1 is to use a user-defined Composite tag like the "BigImage" tag in the example config file

exiftool -config example.config -b -bigimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -overwrite_original -common_args --ext jpg DIR

Even better, thanks for pointing out the BigImage composite tag in example.config, it looks more robust than the command line, I'll go with that.

As an additional possible preview, some editing software (for example, ACDSee), keeps a cached preview of any edited raw file in a "hidden" subfolder. How could I integrate the content of a file in to BigImage?

Slurp the whole image off disk and push it on to the array @$val?


        # [advanced] select largest JPEG preview image
        BigImage => {
            Groups => { 2 => 'Preview' },
            Desire => {
                0 => 'JpgFromRaw',
                1 => 'PreviewImage',
                2 => 'OtherImage',
                # (DNG and A100 ARW may be have 2 PreviewImage's)
                3 => 'PreviewImage (1)',
            },
            # ValueConv may also be a code reference
            # Inputs: 0) reference to list of values, 1) ExifTool object
            ValueConv => sub {
                my $val = shift;

                # Can I add the content of file '[Devoloped]/%f.%e.jpg' to @$val?

                my ($image, $bigImage, $len, $bigLen);
                foreach $image (@$val) {
                    next unless ref $image eq 'SCALAR';
                    # check for JPEG image (or "Binary data" if -b not used)
                    next unless $$image =~ /^(\xff\xd8\xff|Binary data (\d+))/;
                    $len = $2 || length $$image; # get image length
                    # save largest image
                    next if defined $bigLen and $bigLen >= $len;
                    $bigLen = $len;
                    $bigImage = $image;
                }
                return $bigImage;
            },


Or, am I best sticking to "exiftool -o" for exatracting a copy of those when I want them?

Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 07, 2017, 12:47:08 PM
It would require some specialized programming to load an external file from a user-defined tag.  Not really how ExifTool is designed.  So I you should handle those separately, maybe be copying with "exiftool -o" as I think you are suggesting.

- Phil
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 08, 2017, 07:07:42 AM
In my script I've added a -writeMode cg option, a bit like this:

exiftool -b -jpgfromraw -w %d%f_%ue.jpg -execute -if 'not $jpgfromraw' -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -srcfile %d%f_%ue.jpg -writeMode cg -overwrite_original -common_args --ext jpg DIR

Because I can't guarantee that the .jpg was created by this command (exiftool does not overwrite images), and I don't want to overwrite values that have been added explicitly, the wriiteMode option will only add tags that do not exist at all.

Maybe that's worth adding to the example doc?
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 08, 2017, 07:57:35 AM
Good idea.  Thanks for the suggestion, but I fear that adding the -wm option to that example would make it too complex for even an advanced example.

But maybe I could add an option to not run a command if the previous command returned an error status.  Let me think about this.

- Phil
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 08, 2017, 09:05:33 AM
Better a complicated example than one that overwrites or misses data perhaps? (And you are about to simplify it by removing an 'if' :) )

"Stop on error" was what I was originally looking for but -writeMode cg covered what I need in this case.

My testing threw up another wrinkle: the most up-to-date metadata is in the .xmp sidecar file if it exists, I only want to copy missing tags from the raw file, or all tags when there is no .xmp.

So I have also now added -tagsFromFile @ -tagsFromFile %d%f.xmp to the command. I think that that is including all the usual tags from the raw file, and with the latest values and any additional tags from the .xmp if any have been set. Is that correct?

exiftool -b -jpgfromraw -w %d%f_%ue.jpg -execute -if 'not $jpgfromraw' -b -previewimage -w %d%f_%ue.jpg -execute -tagsfromfile @ -tagsFromFile %d%f.xmp -srcfile %d%f_%ue.jpg -writeMode cg -overwrite_original -common_args --ext jpg DIR
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 08, 2017, 10:39:15 AM
Your new command will read all tags from the raw file, then read all tags from the xmp file (overriding any same-named tags from the raw file), then write only tags that already exist in the jpg.

- Phil
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 08, 2017, 11:12:05 AM
Oh dear, that would be almost the opposite of what I wanted :( However, it's not what I see when I test it :)

- Extracted PreviewImage "test_RAW.jpg" has no metadata after extraction (tested separately)
- All appropriate metadata is written in to test_RAW.jpg with the -wm cg option
- If test_RAW.jpg already exists with metadata before running the command then new tags are created if they have been added in the Raw or XMP
- Existing tags in test_RAW.jpg will not be overwritten

Exiftool 10.60.

I used an arg file to test rather than a command line, but the options are the same.




Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: Phil Harvey on December 08, 2017, 11:22:47 AM
Sorry,

I meant this:

Your new command will read all tags from the raw file, then read all tags from the xmp file (overriding any same-named tags from the raw file), then write only tags that don't exist in the jpg.

- Phil
Title: Re: -if with -execute (extracting jpeg previews from raw files)
Post by: busywait on December 08, 2017, 11:39:50 AM
Great, thanks - and that's exactly what I want, and what I'm seeing happen.

There's a warning when the .xmp file doesn't exist, but that's maybe useful ouput to see anyway.