• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Can I automate the writing of XMP metadata into JPEG and TIFF files?

New Here ,
Oct 31, 2008 Oct 31, 2008

Copy link to clipboard

Copied

I have written an ASP.NET 3.5 website application on behalf of an annual international photographic competition. Entrants will be uploading digital photos in either JPEG or TIFF format. Ideally, I would write entrant identity and image title information into the XMP metadata for each image immediately after upload - but so far, I have failed to find any way to do this in ASP.NET.

Thousands of images are involved, so I need to find a way to automate the metadata insertion, perhaps with some sort of script that uses a text file (extracted from the SQL Server database on my website) as the source of the metadata for a batch of images. Is this the sort of task that can be done by writing a script for Bridge CS3? Are there any scripts already in existence that I could use? I am a total beginner in this area.

I use a Win XP PC, though I have a colleague who, I think, has CS3 on his Mac (running under the Leopard OS), so scripts for either platform might be usable.

David
TOPICS
Scripting

Views

9.8K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
replies 104 Replies 104
New Here ,
Nov 11, 2008 Nov 11, 2008

Copy link to clipboard

Copied

Paul,
I think you've cracked it! All the failing images have an '&' in the metadata. Thanks for sticking with it. It's nearly midnight here in the UK, so it's time for my bed too!

David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 11, 2008 Nov 11, 2008

Copy link to clipboard

Copied

A quick check shows that Photoshop will let me manually add metadata containing an ampersand, so it must be a scripting issue.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

I'am in the UK as well.
Now I know what the problem was, I checked how CS3 managed & and it changes it to & So the script has now been amended to cope with &
Here is the modified code and all the error line commented out so that the error log should be more readable.
Please could you test this version with some & in David?
There is a problem posting the code.
In the code there is REPLACEME replace this with a mp; but no space between the a and mp;



#target bridge

if( BridgeTalk.appName == "bridge" ) {

addInfo = MenuElement.create("command", "Update Entry Details", "at the end of Thumbnail");

}

addInfo .onSelect = function () {

mainTitleAuthor();

}



function mainTitleAuthor(){

var csv = File.openDialog("Please select CSV file.","CSV File:*.csv");

if(csv != null){

var errorlog = new File("~/ErrorLog.txt");

errorlog.open('w');

errorlog.writeln("These documents have not been updated");

csv.open("r");

while(!csv.eof){

strInputLine = csv.readln();

errorlog.writeln("=================================================================");

// errorlog.writeln("Line From CSV File: " + strInputLine);

if (strInputLine.length > 3) { // Make sure it isn't a blank line

strInputLine = strInputLine.replace(/\\/g,'/'); //Change backslash to forward slash.

strInputLine = strInputLine.replace(/&/g,"&REPLACEME");

inputArray = strInputLine.split(",");

var csvFile = new File(inputArray[0]);

var title = inputArray[1];

var author = inputArray[2];

// errorlog.writeln("Ok can read file Checking if File Exists : " +decodeURI(csvFile));

if(!csvFile.exists) errorlog.writeln(decodeURI(csvFile) + " ****Does Not Exist****");

if(csvFile.exists){ //Check if file exists

item = new Thumbnail(csvFile);

md =item.synchronousMetadata;

// errorlog.writeln("File Exists" +decodeURI(csvFile) +inputArray[1]+" - " + inputArray[2]);

var result =addTitleAuthor(md,inputArray[1],inputArray[2]);

if(!result) errorlog.writeln(decodeURI(csvFile) + " Unable to apply template");

// errorlog.writeln("Back from creating/apply Template");

}

}

}

}

errorlog.close();

errorlog.execute();

}



function addTitleAuthor(metadata, Title, Author)

{

var strTmpl = "TempTmpl";

var strUser = Folder.userData.absoluteURI;

var filTmpl = new File(strUser + "/Adobe/XMP/Metadata Templates/" + strTmpl + ".xmp");

var fResult = false;



if (filTmpl.exists) filTmpl.remove();

try{

fResult = filTmpl.open("w");

}catch(e){

alert("Unable to create Template " +filTmpl +"\r"+e.message);

return;

}

try{

if (fResult){

//CS3

//filTmpl.writeln("<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"Adobe XMP Core 4.1-c037 46.282696, Mon Apr 02 2007 18:36:42 \">");

//CS2

filTmpl.writeln("<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"3.1.2-113\">");

filTmpl.writeln("<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">");

filTmpl.writeln("<rdf:Description rdf:about=\"\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">");

filTmpl.writeln("<dc:title>");

filTmpl.writeln("<rdf:Alt>");

filTmpl.writeln("<rdf:li xml:lang=\"x-default\">"+Title+"</rdf:li>");

filTmpl.writeln("</rdf:Alt>");

filTmpl.writeln("</dc:title>");

filTmpl.writeln("<dc:creator>");

filTmpl.writeln("<rdf:Seq>");

filTmpl.writeln("<rdf:li>" + Author + "</rdf:li>");

filTmpl.writeln("</rdf:Seq>");

filTmpl.writeln("</dc:creator>");

filTmpl.writeln("</rdf:Description>");

filTmpl.writeln("</rdf:RDF>");

filTmpl.writeln("</x:xmpmeta>");

fResult = filTmpl.close();

metadata.applyMetadataTemplate(strTmpl, "replace");

} }

catch(e) {

alert("There was a problem with the Template");

fResult = false;

}

return fResult;

};

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Paul,
Unfortunately, that gives me an error log as follows:

These documents have not been updated
=================================================================
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C3-1261 Moray &REPLACEME Max.jpg ****Does Not Exist****
=================================================================
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C4-1261 Lola &REPLACEME the girls.jpg ****Does Not Exist****
=================================================================
/c/Program Files/Adobe/Adobe Bridge/"C:/Documents and Settings/Administrator/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C4-1261 Die Nieuwe Kerk ****Does Not Exist****
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C1-1261 Moray &REPLACEME Max.jpg ****Does Not Exist****
=================================================================

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Oops! Just read your post properly. Will try again!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Even after changing REPLACEME as you suggested, I get a very similar error log:

These documents have not been updated
=================================================================
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C3-1261 Moray & Max.jpg ****Does Not Exist****
=================================================================
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C4-1261 Lola & the girls.jpg ****Does Not Exist****
=================================================================
/c/Program Files/Adobe/Adobe Bridge/"C:/Documents and Settings/Administrator/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C4-1261 Die Nieuwe Kerk ****Does Not Exist****
=================================================================
~/My Documents/Visual Studio 2008/WebSites/SIEWebsite/EntryImages/C1-1261 Moray & Max.jpg ****Does Not Exist****
=================================================================

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Ah, now I see why you wrote it as 'a mp;'. In the above error log, please read every ampersand as being &a mp;

Needless to say, these files DO exist (with a real ampersand in the filenames).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

I should also mention that the Die Nieuwe Kerk image is failing because of the embedded comma, as previously discussed, so that error can be ignored.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Oh dear, back to the drawing board.I will have a go later on.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Lets hope I have got it right this time!
It should now ignore & in the filenames but change them in the title and author fields.
So the forum doesn't spoil the code I have uploaded it to PS-Scripts and you can download it there.
http://ps-scripts.com/bb/viewtopic.php?p=9914#9914

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Paul,
As far as I can see, this latest version works perfectly! Thanks yet again for all your hard work. It really is appreciated.

Next year, I plan to buy a big fat textbook on Javascript. Any recommendations?

David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

Great, it's nice when it eventually works!

As far as the book goes there isn't one. The best place is PS-Scripts.com the amount of information you can find there is famtastic also the moderators are wonderful and really do know thier stuff!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

I understood that Extendscript was simply Adobe's flavour of Javascript, and there is certainly no shortage of Javascript books (Amazon lists 280 of them!). Is Extendscript actually more different from Javascript than I have been assuming?

Thanks for the info about PS-Scripts.com, which I hadn't heard of until I used it for your script download.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 12, 2008 Nov 12, 2008

Copy link to clipboard

Copied

David_C_Anderson@adobeforums.com wrote:
> I understood that Extendscript was simply Adobe's flavour of Javascript, and there is certainly no shortage of Javascript books (Amazon lists 280 of them!). Is Extendscript actually more different from Javascript than I have been assuming?
>

Get JavaScript: The Definitive Guide by Flanagan. I always have a copy with in
arm's reach when I work.

There are always differences in JS implementations. Built in XML/XPath support
varies from vendor to vendor, for instance, but the Flanagan book covers the
core language very well. Between that and the JavaScript Tools Guide (that comes
with PS, Bridge, etc... and covers Adobe's ESTK extensions) you'll have just
about all the reference material that is available.

-X

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 10, 2009 Jan 10, 2009

Copy link to clipboard

Copied

Hi Paul,
If you are still watching this thread, I would appreciate it if you could indicate which of the many flavours of your script posted above would work with CS4. I have just upgraded and assume that your final CS2 version (as posted on ps-scripts.com) would no longer be appropriate.

Regards,
David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 10, 2009 Jan 10, 2009

Copy link to clipboard

Copied

Just tested that version on CS4 and it still works fine.
All the best Paul.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 10, 2009 Jan 10, 2009

Copy link to clipboard

Copied

Paul,
Thanks for the rapid reply.

David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 12, 2009 Jan 12, 2009

Copy link to clipboard

Copied

Paul,
I ran your script successfully last night against a list of over 600 image files. It took 13 minutes to complete the process, which highlighted the fact that there is no progress indication of any sort, not even an hourglass symbol. I can live with that, but is there an easy fix?

Also, would it be easy to add the Country field to the metadata list, i.e. in addition to Title and Author?

BTW, I bought myself a book on Javascript but have not yet had time to read it!

Regards,
David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 12, 2009 Jan 12, 2009

Copy link to clipboard

Copied

Ok I have updated the script to add the Country field (last field) I have also attempted to include a progress bar (First time) hope it works.
Same as last time the updated script can be found here:-
http://ps-scripts.com/bb/viewtopic.php?p=10463#10463

Hope you have fun reading the new book!
Paul

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jan 12, 2009 Jan 12, 2009

Copy link to clipboard

Copied

Paul,
A quick test suggests that you have done a perfect job of implementing both of my requests. Once again, let me say how grateful I am for your assistance. The closing date for entries to our international photo salon is the end of January. and this script will be extremely useful.

BTW, does this script run equally well on a Mac? If so, are there any prerequisites for this to work? I use a PC but my colleague uses a Mac of some flavour or other.

David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 12, 2009 Jan 12, 2009

Copy link to clipboard

Copied

I would think that it should work on a Mac but haven't tested it. You shouldn't need to change anything.
All the best, Paul.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
Jan 14, 2009 Jan 14, 2009

Copy link to clipboard

Copied

Paul,<br /><br />I think perhaps one of the problems with our original approach, using XMPScript, is that the Dublin Core "title" property is a LangAlt type, and not a simple array, so...<br /><br />xmp.appendArrayItem(XMPConst.NS_DC, "title", title, 0,XMPConst.ARRAY_IS_ORDERED); <br /><br />Is not setting the metadata correctly. I see that in the versions of the scripts where you are creating XMP XML, you are using the LangAlt type, for example...<br /><br />filTmpl.writeln("<rdf:li xml:lang=\"x-default\">"+Title+"</rdf:li>"); <br /><br />Instead you should use the setLocalizedText() function. Here is an example that uses the setLocalizedText function...<br /><br />#target bridge<br /><br />// Load XMPScript if it's not already<br />if( ! ExternalObject.AdobeXMPScript ) {<br /> ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");<br />}<br /><br />var x = new XMPMeta();<br /><br />$.writeln( $.locale );<br /><br />try {<br /> x.appendArrayItem( XMPConst.NS_DC, "creator", "John Doe", 0, XMPConst.ARRAY_IS_ORDERED );<br /> x.setLocalizedText( XMPConst.NS_DC, "title", null, "en-US", "Hello World" );<br /><br />} catch( e ) {<br /> $.writeln("ERROR: " + e );<br />}<br /><br />$.writeln( x.dumpObject() );<br /><br />This will produce the following output in the JavaScript console in ESTK:<br /><br />Dumping XMPMeta object "" (0x0)<br /><br /> dc: http://purl.org/dc/elements/1.1/ (0x80000000 : schema)<br /> dc:creator (0x600 : isOrdered isArray)<br /> [1] = "John Doe"<br /> dc:title (0x1E00 : isLangAlt isAlt isOrdered isArray)<br /> [1] = "Hello World" (0x50 : hasLang hasQual)<br /> ? xml:lang = "x-default" (0x20 : isQual)<br /> [2] = "Hello World" (0x50 : hasLang hasQual)<br /> ? xml:lang = "en-US" (0x20 : isQual)<br /><br />Adobe apps (at least up to CS4, which is the latest as I write) select and set only the "x-default" member of LangAlt arrays, however the setLocalizedText function seems picky and requires that you specify an actual language string -- and you should use a valid RFC 3066 string, like "en-US" (or one local to you). Whatever string you use, the x-default one will be set. <br /><br />Here is another example, that extends the above, using XMPFiles to write the XMP into a JPEG file. I also added an example setting one of the IPTC Core Creator Contact Info fields, since this uses another helper function from XMPScript, setStructField.<br /><br />#target bridge<br /><br />// Load XMPScript if it's not already<br />if( ! ExternalObject.AdobeXMPScript ) {<br /> ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");<br />}<br /><br />// Make a JPEG for test purposes<br />var curFolder = new File( $.fileName ).parent;<br />var jpeg = new File( curFolder.fsName + "/TestMe.jpg" );<br /><br />var bitmap = new BitmapData( 300, 200 );<br /><br />app.syncronousMode = true;<br />bitmap.exportTo( jpeg );<br />app.syncronousMode = false;<br /><br />var x = new XMPMeta();<br /><br />try {<br /> <br /> x.appendArrayItem( XMPConst.NS_DC, "creator", "John Doe", 0, XMPConst.ARRAY_IS_ORDERED );<br /> x.setLocalizedText( XMPConst.NS_DC, "title", null, "en-US", "Hello World" );<br /> <br /> // Set one of the IPTC Core reator properties<br /> x.setStructField( XMPConst.NS_IPTC_CORE, "CreatorContactInfo", XMPConst.NS_IPTC_CORE, "CiAdrCtry", "United States of America" );<br /><br /> $.writeln( x.dumpObject() );<br /><br /> // Opent he file with XMPFiles<br /> var xmpFile = new XMPFile( jpeg.fsName, XMPConst.FILE_UNKNOWN, XMPConst.OPEN_FOR_UPDATE | XMPConst.OPEN_USE_SMART_HANDLER );<br /><br /> if( xmpFile.canPutXMP( x ) )<br /> {<br /> xmpFile.putXMP(x);<br /> }<br /><br /> xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);<br /><br />} catch( e ) {<br /> $.writeln("ERROR SETTING METADATA: " + e );<br />}<br /><br />-David<br /><br />-David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 15, 2009 Jan 15, 2009

Copy link to clipboard

Copied

Thanks David, yes but this was for CS2 and I didn't think you could use AdobeXMPScript is this the case?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
Jan 15, 2009 Jan 15, 2009

Copy link to clipboard

Copied

Paul,

Right, XMPScript is only available in CS3 and CS4, and not for CS2. I just wanted to add an example of how to set a LangAlt and struct field using XMPScript, because those are two areas where folks might be confused.

Also, for a server-side hosted solution, folks might want to look into using the XMP Toolkit SDK. It includes the C++ implementation of XMPFiles for Windows and Mac. The C++ and JavaScript APIs for XMPFiles are as close to identical as is probably possible given the differences between the two languages.

-David

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Jan 15, 2009 Jan 15, 2009

Copy link to clipboard

Copied

Thank you very much David, it's always good to get great information!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines