Hi all,
I'd like to copy filename to keywords. I've read this forum but I can't find a solution to my case.. So if someone could help me and tell me how to do that I'll be very happy. I don't have any javascript skills, so if someone would push me forward, that'll be nice.
I'm using Bridge CS3, MacOS 10.5.8. I'd like to use it with Automator, or if someone has better solution, please let me know.
Thanks,
Pete
This should do it..
#target bridge
addNametoMeta = {};
addNametoMeta.execute = function(){
var sels = app.document.selections;
for (var i = 0; i < sels.length; i++){
var md = sels[i].synchronousMetadata;
md.namespace = "http://ns.adobe.com/photoshop/1.0/";
md.Keywords = md.Keywords + ";" + sels[i].name;
}
}
if (BridgeTalk.appName == "bridge"){
var menu = MenuElement.create( "command", "Save Filename in Keywords", "at the end of Tools");
menu.onSelect = addNametoMeta.execute;
}
Start Bridge
Edit - Preferences - Startup Scripts
Click the "Reveal" button, this will open the folder where the script should be put.
Close and re-start Bridge, accept the new script.
Select the documents that require the filename added and then select the script from the bottom of the Tools menu.
Hope this helps.
Sorry my bad english..
I'd like to remove the filetype extension from keywords. Filename is copying ok, but extension ".tif" or ".jpg" goes also to keywords. If it's possible to remove filetype extension so that'll not be shown in keywords? Is it possible?
I'll remove filetype extensions now manually. That's because of the structure of the imagebank I'm using, the imagebank doesn't recognize keywords if they're not exact, keywords have to be without dots (.) The search engine doesn't find anything if I'm typing "image", if the image contains "image.tif" in keywords...
Thanks again for helping me, =)
Pete
This will put the filename only no extension..
#target bridge
addNametoMeta = {};
addNametoMeta.execute = function(){
var sels = app.document.selections;
for (var i = 0; i < sels.length; i++){
var md = sels[i].synchronousMetadata;
md.namespace = "http://ns.adobe.com/photoshop/1.0/";
var Name = decodeURI(sels[i].name).replace(/\.[^\.]+$/, '');
md.Keywords = md.Keywords + ";" + Name;
}
}
if (BridgeTalk.appName == "bridge"){
var menu = MenuElement.create( "command", "Save Filename in Keywords", "at the end of Tools");
menu.onSelect = addNametoMeta.execute;
}
What if I wanted to use the name of the folder the files are in rather than the file name?
Say, I have a folder and within it many subfolders. I want to display all of the files within that folder and its subfolders, select all images and transfer the subfolder names into Description filed in IPTC.
Thank you for your help.
This should do it....
#target bridge
if( BridgeTalk.appName == "bridge" ) {
addFolderName = MenuElement.create("command", "Add FolderName to Description", "at the end of Tools");
}
addFolderName.onSelect = function() {
addFolderNameToDescription();
}
function addFolderNameToDescription(){
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
var sels = app.document.selections;
for(var a in sels){
var thumb = sels[a];
if(thumb.type != 'file') continue;
app.synchronousMode = true;
var xmp = new XMPMeta(thumb.synchronousMetadata.serialize());
xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", sels[a].spec.parent.name );
var newPacket = xmp.serialize(XMPConst.SERIALIZE_USE_COMPACT_FORMAT);
thumb.metadata = new Metadata(newPacket);
}
}
Please try this now...
#target bridge
if( BridgeTalk.appName == "bridge" ) {
addFolderName = MenuElement.create("command", "Add FolderName to Description", "at the end of Tools");
}
addFolderName.onSelect = function() {
addFolderNameToDescription();
}
function addFolderNameToDescription(){
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
var sels = app.document.selections;
for(var a in sels){
var thumb = sels[a];
if(thumb.type != 'file') continue;
app.synchronousMode = true;
var xmp = new XMPMeta(thumb.synchronousMetadata.serialize());
xmp.setLocalizedText( XMPConst.NS_DC, "description", null, "x-default", decodeURI(sels[a].spec.parent.name) );
var newPacket = xmp.serialize(XMPConst.SERIALIZE_USE_COMPACT_FORMAT);
thumb.metadata = new Metadata(newPacket);
}
}
Hello Paul,
Thank you for these scripts!
I'm trying to tweak this script to write the Folder Name to the IPTC Keyword field instead of the Description field. This works (when I substitute "subject" for "description") but only when the Keyword field is empty.
What's the trick to append keywords?
Thank you in advance,
-Saïd
Please try this...
#target bridge
addFolderNametoMeta = {};
addFolderNametoMeta.execute = function(){
var sels = app.document.selections;
for (var i = 0; i < sels.length; i++){
var md = sels[i].synchronousMetadata;
md.namespace = "http://ns.adobe.com/photoshop/1.0/";
md.Keywords = md.Keywords + ";" + decodeURI(sels[i].spec.parent.name);
}
}
if (BridgeTalk.appName == "bridge"){
var menu = MenuElement.create( "command", "Save FolderName in Keywords", "at the end of Tools");
menu.onSelect = addFolderNametoMeta.execute;
}
Thanks Paul.
Works like a charm!
i'd tried
> decodeURI(sels[a].spec.parent.name)
that I pulled form another script but, of course, that didn't work.
You've rescued me from disorientation in the Javascript Tools Guide, popping various Folder Object Properties and hoping one would work ;-)
Naturally, no good deed goes unpunished! (Though if you have a solution to this following one then I will donate to your favorite charity).
The next time-saving query that comes to mind is this: File and Folder names are (for me) often concatenated. This means when I add them to Keywords, I must manually edit the text to return it to individual (hence searchable) words. Is there a way to run a script such as this so that the filename (for example) pops up in a dialogue box for manual editing before applying to the XMP field? This would be a real timesaver when applying this script to batches of files.
Much Obliged
-Saïd
Hi Said, glad that worked, I wonder if this script might help you?
http://www.ps-scripts.com/bb/viewtopic.php?f=19&t=2364&sid=c8a1c6d5d06 e0a1127cc473f6ac3466d
There it is! Sweet.
Doesn’t quite do what I had in mind (automatically populate
the Replace field with the keyword(s) for subsequent editing)
but after a good night’s sleep, I think this will work fine.
My thought would be next-to-impossible to implement on batches.
Well... unless the dialogue contained a “Go to next file”
button and automatically re-populated the Replace field.
However, this beggar will not be choosy.
Thanks much
Hi Paul,
as it seems you´re the godfather of scripting ... and now I need your help.
I´m working on CS4, Windows XP and I have more than 1500 folders in Bridge containing up to 15 pictures to handle.
I want the name of the folder written in one of the iptc fields, doesn´t matter if it´s the keyword or description. Unfortunately, in some of the pictures these fields are already filled out, so I want to add the foldername.
Due to the fact that I don´t know how to handle java and how to save it, I really appreciate your help.
Edit: I finally got it working, but now I have the problem that the folder contains other folders in which are the pictures ...
Example:
Folder XY
Just the folders "other name" are filled with pictures but I need the "Folder XY" written in the IPTC-fields.
Can you help ?
Kind regards and thanks a lot !
Alex
If you want the Parent folder name you can use this..
#target bridge
addFolderNametoMeta = {};
addFolderNametoMeta.execute = function(){
var sels = app.document.selections;
for (var i = 0; i < sels.length; i++){
var md = sels[i].synchronousMetadata;
md.namespace = "http://ns.adobe.com/photoshop/1.0/";
md.Keywords = md.Keywords + ";" + decodeURI(sels[i].spec.parent.parent.name);
}
}
if (BridgeTalk.appName == "bridge"){
var menu = MenuElement.create( "command", "Save FolderName in Keywords", "at the end of Tools");
menu.onSelect = addFolderNametoMeta.execute;
}
Or if you want to do ALL subfolders this might do..
You need to be in the top level folder.
This also removes duplicates in the keyword field.
Amend the folder name to suit....
#target bridge
if( BridgeTalk.appName == "bridge" ) {
AddFolderNameToMeta = MenuElement.create("command", "Add FolderName to Files", "at the end of Tools");
}
AddFolderNameToMeta.onSelect = function () {
addFolderName();
}
function addFolderName(){
var folders =[];
var Pics=0;
folders = FindAllFolders(Folder(app.document.presentationPath), folders);
folders.unshift(Folder(app.document.presentationPath));
for(var a in folders){
var PictureFiles = folders[a].getFiles(/\.(jpg|jpe|jpeg|gif|eps|dng|bmp|tif|tiff|psd|rle|dib|cin|dpx|sct|pbm|flm|psb|exr|pcx|pdp|nef|dcr|dc2|erf|raf|orf|tga|mrw|mos|srf|pic|pct|pxr|pdd|pef|png|x3f|raw)$/i);
for(var p in PictureFiles){
addKeyword(PictureFiles[p])
Pics++;
}
}
alert("Number of Folders Processed = "+folders.length+ " Documents Processed = "+Pics);
function addKeyword(fileName){
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
var thumb = new Thumbnail(fileName);
var folderName = decodeURI(fileName.parent.name);
//Or if you want the folders Parent use the line below.
//var folderName = decodeURI(fileName.parent.parent.name);
if(thumb.hasMetadata){
var selectedFile = thumb.spec;
try{
var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = myXmpFile.getXMP();
var keys = getArrayItems(XMPConst.NS_DC,'subject');
keys.unshift(folderName);
keys= ReturnUniqueSortedList(keys);
myXmp.deleteProperty(XMPConst.NS_DC,'subject');
for(var z in keys){
myXmp.appendArrayItem(XMPConst.NS_DC, "subject", keys[z], 0,XMPConst.PROP_IS_ARRAY);
}
}catch(e){}
if (myXmpFile.canPutXMP(myXmp)) {
myXmpFile.putXMP(myXmp);
myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
}
}
function getArrayItems(ns, prop){
var arrItem=[];
var items = myXmp.countArrayItems(ns, prop);
for(var i = 1;i <= items;i++){
arrItem.push(myXmp.getArrayItem(ns, prop, i));
}
return arrItem;
}
};
function FindAllFolders( srcFolderStr, destArray) {
var fileFolderArray = Folder( srcFolderStr ).getFiles();
for ( var i = 0; i < fileFolderArray.length; i++ ) {
var fileFoldObj = fileFolderArray[i];
if ( fileFoldObj instanceof File ) {
} else {
destArray.push( Folder(fileFoldObj) );
FindAllFolders( fileFoldObj.toString(), destArray );
}
}
return destArray;
}
function ReturnUniqueSortedList(ArrayName){
var unduped = new Object;
for (var i = 0; i < ArrayName.length; i++) {
unduped[ArrayName[i]] = ArrayName[i];
}
var uniques = new Array;for (var k in unduped) {
uniques.push(unduped[k]);
}
uniques.sort();
return uniques;
}
};
Good morning, Paul and thanks so much for your help.
Unfortunately, both scripts won´t work the way I wanted it - either I´m doing something wrong or my description of the way the script should work was too complicated.
First of all, I describe you what I did:
I marked the parent folder in Bridge without showing the assets in the subfolders, then start the script. The first (short) script has no effect at all, the second (long) script is working, the message pops up and tells me, what the script did. But: The second script puts the name of the subfolders in IPTC but not the name of the parent folder.
At the screenshot you can see an example how the structure is and what I´m looking for.
The name of the folder "This folder name in IPTC" (the parent folder) is the information I want to be written in the IPTC-information of the pictures in Subfolder_01
Is this possible too ? Or did I something wrong ?
Thanks a lot once again,
Alex
This should do it, hope it works for you..
#target bridge
addFolderNametoMeta = {};
addFolderNametoMeta.execute = function(){
var sels = app.document.selections;
for (var i = 0; i < sels.length; i++){
var md = sels[i].synchronousMetadata;
md.namespace = "http://ns.adobe.com/photoshop/1.0/";
md.Keywords = md.Keywords + ";" + decodeURI(sels[i].spec.name).substring(0,7);;
}
}
if (BridgeTalk.appName == "bridge"){
var menu = MenuElement.create( "command", "Add First 7 to Keywords", "at the end of Tools");
menu.onSelect = addFolderNametoMeta.execute;
}
Wonderful. I've been searching hi and lo for the solution to my problem. This is getting very close. I have a need of a slight modification: Getting back to the basic request of "filename to IPTC Title", I want to put the filename into my OWN datafield that is NOT IPTC. I'm wondering where in this code I can apply my own namespace and datafield name, and if it would work with that simple change, or would I need to modify the Adobe libraries as well?
See if this helps....
#target bridge
if( BridgeTalk.appName == "bridge" ) {
addFileName = MenuElement.create("command", "Add FileName to My New Field", "at the end of Tools");
}
addFileName.onSelect = function() {
if ( !ExternalObject.AdobeXMPScript ) ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
//Your unique name space
var psNamespace = "http://my.uniqueNameSapce/1.0/";
//Your chosen prefix
var psPrefix = "myPre:";
//Register namespace and prefix
XMPMeta.registerNamespace(psNamespace, psPrefix);
var sels = app.document.selections;
for(var a in sels){
var thumb = sels[a];
if(thumb.type != 'file') continue;
app.synchronousMode = true;
var xmp = new XMPMeta(thumb.synchronousMetadata.serialize());
var Name = decodeURI(sels[a].name).replace(/\.[^\.]+$/, '');
//Create new field "MyTitile" add file name to it.
xmp.setProperty( psNamespace, "MyTitle", Name);
var newPacket = xmp.serialize(XMPConst.SERIALIZE_USE_COMPACT_FORMAT);
thumb.metadata = new Metadata(newPacket);
}
}
North America
Europe, Middle East and Africa
Asia Pacific