Copy link to clipboard
Copied
This short test script used to work getting a files description in Bridge, but now it fails on the line tha has: XMPConst.OPEN_FOR_UPDATE. The error is XMP Exception: OpenFile retuned false. Anyone else having issues with this?
#target bridge
if (ExternalObject.AdobeXMPScript == undefined) {
ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
}
var doc = app.document
var thumbs = doc.selections
for(var i=0;i<thumbs.length;i++){
var tSpec = thumbs[i].spec;
var testFile = new File(tSpec);
readTextFile (testFile)
};//end for thumbs loop
function readTextFile(file){
var xmpf = new XMPFile(File(file).fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE );
var xmp = xmpf.getXMP();
var des = xmp.getProperty(XMPConst.NS_DC, "description").toString();
alert(des)
xmpf.closeFile( XMPConst.CLOSE_UPDATE_SAFELY );
}
Because you can't read XMP from a RAW file. You have to use thumbnails not file specs.
OP, use thumbnails and synchronousMetadata instead of file spec.
XMPdesc();
XMPdesc = function(){
var descThumbs = app.document.selections; //get selected thumbnails
var newText = 'test'; //replacement text
if(!descThumbs.length) return; //nothing selected
for(var a in descThumbs){ //loop through thumbs
if(!descThumbs[a].container){ //not a folder
try{
var descMeta = descThumbs[a].synchronousMetadata; //get metadata
...
Copy link to clipboard
Copied
I am not getting the OpenFile error in Bridge 12.0.0.234
Your script worked, except that I didn't get a value for var des = xmp.getProperty(XMPConst.NS_DC, "description").toString();
so I changed it to this:
var des = xmp.getArrayItem(XMPConst.NS_DC, "description",1).toString();
Copy link to clipboard
Copied
Thanks for the update.
Copy link to clipboard
Copied
Still terrible at understanding metadata. What's the 1 for after description? Examples that have multiple entries, I'm guessing that it's semicolon delimited, but is there a default value for 0? Or rather why does it start at 1 in this case?
Copy link to clipboard
Copied
dc:description is a language alternate (langAlt) property which means it can have values in different languages. It starts at 1. Generally, only one language is saved using the "x-default" designation, so using 1 will get the only available item.
<dc:description>
<rdf:Alt>
<rdf:li xml:lang="x-default">My description</rdf:li>
</rdf:Alt>
</dc:description>
If your metadata contains multiple language values, it possible to read a specific one, like "en-US" using getLocalizedText(). Most times only "x-default" is used, so getArrayItem(XMPConst.NS_DC, "description",1) works fine.
There are two other array type properties, bag and seq. These contain individual items and are generally displayed in the UI as one string using semi-colon or comma separators.
Copy link to clipboard
Copied
Seems to be working with PSD files, but not raw NEF files.
Copy link to clipboard
Copied
Because you can't read XMP from a RAW file. You have to use thumbnails not file specs.
OP, use thumbnails and synchronousMetadata instead of file spec.
Copy link to clipboard
Copied
Thanks!
Copy link to clipboard
Copied
Let me know if you need some sample code.
Copy link to clipboard
Copied
YES! Some sample code would be wonderful.
Copy link to clipboard
Copied
XMPdesc();
XMPdesc = function(){
var descThumbs = app.document.selections; //get selected thumbnails
var newText = 'test'; //replacement text
if(!descThumbs.length) return; //nothing selected
for(var a in descThumbs){ //loop through thumbs
if(!descThumbs[a].container){ //not a folder
try{
var descMeta = descThumbs[a].synchronousMetadata; //get metadata
var descXMP = new XMPMeta(descMeta.serialize()); //serialize
alert(descMeta.read(XMPConst.NS_DC, 'description').toString()); //read description
descXMP.deleteProperty(XMPConst.NS_DC, 'description'); //delete
descXMP.setLocalizedText(XMPConst.NS_DC, 'description', null, 'x-default', newText); //set new description
var descUpdatedPacket = descXMP.serialize(XMPConst.SERIALIZE_OMIT_PACKET_WRAPPER | XMPConst.SERIALIZE_USE_COMPACT_FORMAT); //serialize
descThumbs[a].metadata = new Metadata(descUpdatedPacket); //write to file
}
catch(e){
alert(e + e.line);
}
}
}
}
Copy link to clipboard
Copied
Thanks, so much!
Copy link to clipboard
Copied
You see I used both serialized and synchronous metadata, you could use descXMP.getProperty instead of descMeta.read, whichever works best for you.
Copy link to clipboard
Copied
Thanks! I'll have to play around with it. I'm going to send my siblings a couple thousand family photos, and I'm going to pull all the descriptions off and put them in a pdf for them.
Copy link to clipboard
Copied
You can write these to a text file as you read them. Just skip the code that removes the old description.
Copy link to clipboard
Copied
I'm thinking of just using Bridge to export jpgs for them. It's fairly fast, and they don't need to be opened. I could also then use my original script to create the text file. Just thinking if I want to write a script for saving them that keeps the folder structure.
Copy link to clipboard
Copied
The error occurs when you use .toString(). Then as processed file was not closed (by last code line), the Bridge remembered its open state, so next time it couldn't proceed, unless you restarted application. The solution is to change UPDATE to READ (due to your original question):
!ExternalObject.AdobeXMPScript && ExternalObject
.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript')
slctns = app.document.selections; while(slctns.length) {
xmp = new XMPFile(slctns.shift().spec.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_READ)
try{alert(xmp.getXMP().getLocalizedText(XMPConst.NS_DC, 'description', 0, 0).toString())}catch(err){}
xmp.closeFile(XMPConst.CLOSE_UPDATE_SAFELY)
}
btw please assign Scripting label to your thread 😉