Create two JPGs out of one - language issue

Started by infotalk, August 09, 2011, 07:28:02 AM

Previous topic - Next topic

infotalk

Hello,

I have JPGs with meta informations like this example
German PIPE AS SEPARATOR English

Headline
German Headline | English Headline

Description
German Description | English Description

Keywords
German Keywords | English Keywords

Title
German Title | English Title

Is it possible to create two JPGs out of one with ExifTool in Windows?
One JPG in German language.
One JPG in English language.

Thank you for helping.

Phil Harvey

Yes.

To do this requires creating user-defined tags to isolate the English and German portions of each tag you want to write, so it is a bit of work but is do-able.

- 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 ($).

infotalk

Hi Phil,

can you write an example for the field "headline". I am not very experienced.

Thank you so much.

Phil Harvey

#3
I don't have time to test this out, but the following config file has a chance of doing what you want:

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        HeadlineGerman => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) | (.*)/ ? $1 : undef',
        },
        HeadlineEnglish => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) | (.*)/ ? $2 : undef',
        },
    },
);


This assumes that the descriptions are separated by a space+vertical bar+space sequence.

See the sample config file for instructions on how to activate the config file.

Then the commands could look like:

exiftool -o %d%f-english.%e "-caption<captionenglish" FILE
exiftool -o %d%f-german.%e "-caption<captiongerman" FILE


Where FILE is one or more file or directory names.

- 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 ($).

infotalk

Hi Phil,

Here is my result...


%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        HeadlineGerman => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) | (.*)/ ? $1 : undef',
        },
        HeadlineEnglish => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) | (.*)/ ? $2 : undef',
        },
    },
);


xxxxxxxxxx

exiftool -k -o %d%f-german.%e "-Headline<HeadlineGerman" *.jpg
    1 image files created
-- press any key --

File with original meta information:
Headline: Fachwerkhaus | Half-timbered house

After exiftool -k -o %%d%%f-german.%%e "-Headline<HeadlineGerman" *.jpg
Result headline: Fachwerkhaus | Half-timbered

Description changed from
Fachwerkhaus in Lüneburg, Niedersachsen, Deutschland. | Half-timbered house in Lueneburg, Lower Saxony, Germany.
to
Fachwerkhaus in Lüneburg, Niedersachsen, Deutschland. | Half-timbered house in Lueneburg, Lower Saxony,

Only the last word will be cut off. I think this is due to the fact that I did not mention that there are several words after the pipe.

But nothing happend to the German keywords.
They look like this before and after using ExifTool:
Tag, Tageslicht, Tageszeit, Teilansicht, Verzierung, Vorderansicht, Ziegelstein | architecture, brick, building, cornice, day, daylight, daytime, decoration, detail, edifice, exterior

xxxxxxxxxx

exiftool -k -o exiftool -k -o %d%f-english.%e "-Headline<HeadlineEnglish" *.jpg
Warning: No writable tags found - 00001.jpg
    1 image files copied
-- press any key --

After exiftool -k -o %%d%%f-english.%%e "-Headline<HeadlineEnglish" *.jpg

No changes in English headline. Same with description, keywords and title.

xxxxxxxxxx

Dear Phil PLEASE have a look.

Phil Harvey

Ah, darn!  I forgot a backslash before the "|" symbol (necessary because this symbol has a special meaning in regular expressions):

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        HeadlineGerman => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $1 : undef',
        },
        HeadlineEnglish => {
            Require => 'Headline',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $2 : undef',
        },
    },
);


- 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 ($).

infotalk

Hi Phil,

Thank you very much. Headline, description, title work fine.

The ONLY problem is the keyword-field (IPTC and XMP).

I did some tests and I have noticed, that it worked fine if I have the constellation
GermanKeyword PIPE EnglishKeyword

But it does not work if I have these constellations:
GermanKeyword; GermanKeyword PIPE EnglishKeyword
GermanKeyword PIPE EnglishKeyword; EnglishKeyword
GermanKeyword; GermanKeyword PIPE EnglishKeyword; EnglishKeyword

Is it the semicolon that Adobe Bridge automatically inserts?

I do not know what caused the error.

I would be happy if you could interpret the warnings.


%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        GermanIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $1 : undef',
        },
        EnglishIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $2 : undef',
        },
        GermanXMPSubject => {
            Require => 'XMP:Subject',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $1 : undef',
        },
        EnglishXMPSubject => {
            Require => 'XMP:Subject',
            ValueConv => '$val =~ /(.*) \| (.*)/ ? $2 : undef',
        },
    },
);


exiftool -k -v2 -o %%d%%f-german.%%e "-IPTC:Keywords<GermanIPTCKeywords" "-XMP:Subject<GermanXMPSubject" *.jpg
exiftool -k -v2 -o %%d%%f-english.%%e "-IPTC:Keywords<EnglishIPTCKeywords" "-XMP:Subject<EnglishXMPSubject" *.jpg


Keywords:
rot; grün; blau | red; green; blue


exiftool -k -v2 -o %d%f-german.%e "-IPTC:Keywords<GermanIPTCKeywords" "-XMP:Subject<GermanXMPSubject" *.jpg
======== 00001.jpg
Setting new values from 00001.jpg
Warning: Unknown format (8224) for PreviewIFD tag 0x0 - 00001.jpg
Warning: No writable tags found - 00001.jpg
'00001.jpg' --> '00001-german.jpg'
Rewriting 00001.jpg...
Nothing changed in 00001.jpg
    1 image files copied
-- press any key --


exiftool -k -v2 -o %d%f-english.%e "-IPTC:Keywords<EnglishIPTCKeywords" "-XMP:Subject<EnglishXMPSubject" *.jpg
======== 00001.jpg
Setting new values from 00001.jpg
Warning: Unknown format (8224) for PreviewIFD tag 0x0 - 00001.jpg
Warning: No writable tags found - 00001.jpg
'00001.jpg' --> '00001-english.jpg'
Rewriting 00001.jpg...
Nothing changed in 00001.jpg
    1 image files copied
-- press any key --

xxxxxxxxxx

Keywords:
rot | red


exiftool -k -v2 -o %d%f-german.%e "-IPTC:Keywords<GermanIPTCKeywords" "-XMP:Subject<GermanXMPSubject" *.jpg
======== 00001.jpg
Setting new values from 00001.jpg
Writing IPTC:Keywords
Warning: Unknown format (8224) for PreviewIFD tag 0x0 - 00001.jpg
'00001.jpg' --> '00001-german.jpg'
Rewriting 00001.jpg...
  Editing tags in: APP13 IPTC Photoshop
  Creating tags in: APP13 IPTC Photoshop
JPEG APP1 (25248 bytes):
JPEG APP1 (5412 bytes):
JPEG APP13 (16654 bytes):
  Rewriting Photoshop
  Rewriting IPTC
    + IPTC:EnvelopeRecordVersion = '4' (mandatory)
    - IPTC:Keywords = 'rot | red'
    + IPTC:Keywords = 'rot'
JPEG APP2 (574 bytes):
JPEG APP14 (12 bytes):
JPEG DQT (130 bytes):
JPEG SOF0:
JPEG DRI (2 bytes):
JPEG DHT (416 bytes):
JPEG SOS
    1 image files created
-- press any key --



exiftool -k -v2 -o %d%f-english.%e "-IPTC:Keywords<EnglishIPTCKeywords" "-XMP:Subject<EnglishXMPSubject" *.jpg
======== 00001.jpg
Setting new values from 00001.jpg
Writing IPTC:Keywords
Warning: Unknown format (8224) for PreviewIFD tag 0x0 - 00001.jpg
'00001.jpg' --> '00001-english.jpg'
Rewriting 00001.jpg...
  Editing tags in: APP13 IPTC Photoshop
  Creating tags in: APP13 IPTC Photoshop
JPEG APP1 (25248 bytes):
JPEG APP1 (5412 bytes):
JPEG APP13 (16654 bytes):
  Rewriting Photoshop
  Rewriting IPTC
    + IPTC:EnvelopeRecordVersion = '4' (mandatory)
    - IPTC:Keywords = 'rot | red'
    + IPTC:Keywords = 'red'
JPEG APP2 (574 bytes):
JPEG APP14 (12 bytes):
JPEG DQT (130 bytes):
JPEG SOF0:
JPEG DRI (2 bytes):
JPEG DHT (416 bytes):
JPEG SOS
    1 image files created
-- press any key --

Phil Harvey

#7
List-type tags are considerably more complicated because you must loop through each entry:

        GermanIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$1), next;
                     push(@newKeywords,$_);
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },
        EnglishIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$2);
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },


If there is a single keyword, I assume that it is German.  To do otherwise would require some sort of language recognition module, which ExifTool doesn't have.

- 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 ($).

infotalk

Then I cannot use the code for the keywords as I have for example 10 German words PIPE 15 English words separated by semicolons. Sometimes are phrases included like this: blue, sky, blue sky, cloud.

Phil, thank you very much for helping me!!!

Phil Harvey

#9
Maybe I misunderstood.  I was thinking tag German and English were paired in each Keyword, but that some keywords didn't have both languages, like this:

1) hund
2) fenster | window
3) yellow

But if the order of the keywords is significant, and the German ones always come before the English ones, like this:

1) hund
2) fenster | dog
3) window

This would be a very strange arrangement, but if it is done like this then we can get it to work with these config entries:

        GermanIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$1), last;
                     push(@newKeywords,$_);
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },
        EnglishIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$2), next;
                     push(@newKeywords,$_) if @newKeywords;
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },


- 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 ($).

infotalk

Incredible... it works! PHIL, THANK YOU SO MUCH. This is such a great tool. Donation follows...

infotalk

Hi Phil,

This works for the constellation:

word | word
word, word | word, word, word
word, word, word | word, word

        GermanIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$1), last;
                     push(@newKeywords,$_);
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },
        EnglishIPTCKeywords => {
            Require => 'IPTC:Keywords',
            ValueConv => q{
                $val = [ $val ] unless ref $val eq 'ARRAY';
                my @newKeywords;
                foreach (@$val) {
                     /(.*) \| (.*)/ and push(@newKeywords,$2), next;
                     push(@newKeywords,$_) if @newKeywords;
                }
                return @newKeywords ? \@newKeywords : undef;
            },
        },



What I must change if the VERTICAL BAR is separated by commas like this:

word, |, word
word, word, |, word, word, word
word, word, word, |, word, word

I have tried a lot but...

Thanks in advance!

Phil Harvey

Change /(.*) \| (.*)/ to /^(.*?),? ?\|,? ?(.*?)$/ to allow the commas.  Also, here I have made the spaces optional by adding trailing question marks.  The trick is that once these are optional, the (.*) would have eaten up the spaces and commas too, so I changed this to a minimal match (.*?).

You can learn all about this by googling "regular expressions".

- 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 ($).

infotalk