gregreser
Community Expert
gregreser
Community Expert
Activity
‎May 26, 2021
10:06 AM
ExifTool is good for this, but it's command line and requires a little more work.
You can try this: Adobe Bridge User Customizable Export-Import
... View more
‎May 26, 2021
10:03 AM
I'm not sure if htis meets your needs. It replaces all spaces in title with semicolon+space and adds this to the beginning of the Description. current title = car bus van current description = existing description new description = car; bus; van; existing description #target bridge
if( BridgeTalk.appName == "bridge" ) {
FT = MenuElement.create("command", "description", "at the end of Tools");
}
function loadXMPLib(){
if (ExternalObject.AdobeXMPScript == undefined) {
ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
}
}
FT.onSelect = function () {
var thumbs = app.document.selections;
if(!thumbs.length) return;
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
for(var a in thumbs){
var selectedFile = thumbs[a].spec;
var webshop = ";"
var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = myXmpFile.getXMP();
var countTitle = myXmp.countArrayItems(XMPConst.NS_DC, "title");
var titleString = "";
if(countTitle > 0){
for(var i = 1;i <= countTitle;i++){
try{
titleString += myXmp.getArrayItem(XMPConst.NS_DC, "title", i);
if(i < countTitle) titleString += '; ';
}
catch(propFail){
titleString = "";
}
}
};
var countDesc = myXmp.countArrayItems(XMPConst.NS_DC, "description");
var descString = "";
if(countDesc > 0){
for(var i = 1;i <= countDesc;i++){
try{
descString += myXmp.getArrayItem(XMPConst.NS_DC, "description", i);
if(i < countDesc) descString += '; ';
}
catch(propFail){
descString = "";
}
}
};
var titleStringSeparated = titleString.replace(/ /g, "; ")
var titleDescCombo = titleStringSeparated+"; "+descString;
myXmp.deleteProperty(XMPConst.NS_DC, "description");
myXmp.appendArrayItem(XMPConst.NS_DC, "description", titleDescCombo, 0, XMPConst.ALIAS_TO_ALT_TEXT);
myXmp.setQualifier(XMPConst.NS_DC, "description[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default");
if (myXmpFile.canPutXMP(myXmp)) {
myXmpFile.putXMP(myXmp);
myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
}
}
}
... View more
‎May 25, 2021
08:41 PM
I don't think selectedFile.title will read the current title field, if that's what you are tyring to do. You are doing a lot of changes with multiple scripts. Maybe it would be better to export the metadata to a spreadsheet, fix everything once, then import it back to the images and be finished.
... View more
‎May 25, 2021
04:07 PM
I should have said files from both cameras. I haven't seen this problem in Bridge so I was curious if the raw XMP CreateDate and ModifyDate are correct in files from both cameras. If the XMP date/time is correct, then we could try to figure out why it is not displayng correctly.
... View more
‎May 25, 2021
09:39 AM
I'm curious what date/time was recored in the XMP in both files. Check the raw XMP to see if they are the same. Tools > File Info > Raw Data xmp:CreateDate xmp:ModifyDate
... View more
‎May 25, 2021
07:51 AM
It might be that one of the cameras is set to record the time zone or daylight savings as part of the time metadata. Mac OS is compensating for this but Bridge isn't.
... View more
‎May 18, 2021
02:33 PM
This script has the same problem as your other one... Iptc4xmpCore:Scene is a bag array, not langAlt. What indicates that this script is langAlt? XMPConst.ALIAS_TO_ALT_TEXT myXmp.setQualifier(XNS_IPTC_CORE, "Iptc4xmpCore:Scene"[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default"); Also, the namespace is wrong. NS_IPTC_CORE It should be XMPConst.NS_IPTC_CORE #target bridge
if( BridgeTalk.appName == "bridge" ) {
FT = MenuElement.create("command", "Add Web Scene Code to Scene Code", "at the end of Tools");
}
FT.onSelect = function () {
AddWebSceneToSceneCode();
}
function AddWebSceneToSceneCode(){
var thumbs = app.document.selections;
if(!thumbs.length) return;
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
for(var a in thumbs){
var selectedFile = thumbs[a].spec;
//var WebSceneCode = decodeURI(selectedFile.name)//.replace(/\.[^\.]+$/, '')//([0-9/[-]*/.jpg/]*) nur name
var WebSceneCode = "12345"
var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = myXmpFile.getXMP();
myXmp.deleteProperty(XMPConst.NS_IPTC_CORE, "Iptc4xmpCore:Scene");
myXmp.appendArrayItem(XMPConst.NS_IPTC_CORE, "Iptc4xmpCore:Scene", WebSceneCode, 0, XMPConst.ARRAY_IS_UNORDERED);
if (myXmpFile.canPutXMP(myXmp)) {
myXmpFile.putXMP(myXmp);
myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
}
}
}
... View more
‎May 18, 2021
08:14 AM
It's possible Bridge has not indexed the metadata in that folder, but first you should see if the keywords are in IPTC. Look in the metadata panel for the IPTC Core sections. If you don't any metdata there, then it's not in the IPTC XMP record. You can also look at the actual XMP metadata record by going to File Info > Raw Data. Look for <dc:subject>  
... View more
‎May 17, 2021
04:05 PM
This will remove the second name and year ;.* This will remove the first year also \d{4} ;.* Is this what you were hoping for?    
... View more
‎May 16, 2021
10:56 PM
1 Upvote
The IPTC specification is also very useful. When testing a script or evaluating a metadata issue, it is useful to look at the raw XMP record. In Bridge, go to File Info > Raw Data. This will reveal what is really going on with the metadata.
... View more
‎May 16, 2021
12:32 PM
1 Upvote
There are three types of arrays in XMP 1. bag is an unordered array. The items order in the list do not matter and an application is not costrained to display them in any particular order. For example, keywords (dc:subject) display order is not enforced. 2. seq is an ordered array. The items order in the list is meaningful and applications are expected to display them in the same order as they are written in the XMP. For example, mutliple creators might be listed in order of importance (dc:creator). 3. langAlt (language alternative) is an ordered array and has language qualifiers that allow applications to display a language variant. For example, the copyright notice (dc:rights) could be written to XMP in several languages and the application could display the text that matches the user's system language. Typically, only one languge is saved in XMP using the qualifier "x-default" (meaning it is the default value to be displayed), but it is possible to specify other IETF RFC 3066 language qualifiers. Except for custom scripts, Bridge does not save multiple languages, as far as I know, it is usually "x-default" When writing XMP, it is critical to use the proper XMP property type (there are other types besides arrays) in order to create valid, readable metadata. See the XMP Specification for more info. Part 1, Data model, Serialization, and Core Properties explains property types and has a list of core properties.
... View more
‎May 15, 2021
06:47 PM
The other problem is that Iptc4xmpCore:SubjectCode is not a langAlt array, it's a bag array, so it was being written incorrectly. I added a different substr that will work if your filenames are different lengths and are formatted [charactersYouDoNotwant][8 character IPTC SubjectCode].[3 character extension] #target bridge
if( BridgeTalk.appName == "bridge" ) {
FT = MenuElement.create("command", "Add FileName to IPTC Suject code", "at the end of Tools");
}
FT.onSelect = function () {
AddFilenameToCredit();
}
function AddFilenameToCredit(){
var thumbs = app.document.selections;
if(!thumbs.length) return;
if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript");
for(var a in thumbs){
var selectedFile = thumbs[a].spec;
var str = decodeURI(selectedFile.name);
// works if filename is formatted [charactersYouDoNotwant][8 character IPTC SubjectCode].[3 character extension] example: abcdef20000032.jpg
var Credit = str.substring(str.length-12, str.length-4);
// works if filename is always the same length
//var Credit = str.substr(6, 8);
var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE);
var myXmp = myXmpFile.getXMP();
myXmp.deleteProperty(XMPConst.NS_IPTC_CORE, "Iptc4xmpCore:SubjectCode");
myXmp.appendArrayItem(XMPConst.NS_IPTC_CORE, "Iptc4xmpCore:SubjectCode", Credit, 0, XMPConst.ARRAY_IS_UNORDERED);
if (myXmpFile.canPutXMP(myXmp)) {
myXmpFile.putXMP(myXmp);
myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
}
}
}
... View more
‎May 15, 2021
04:48 PM
I should have asked what is not working. The script runs and writes data, so I assume the problem is that the resulting value is not correct. I got the entire filename written to SubjectCode when I tested it. If your filenames always have the same format this will not be hard. As an example, if your filename is abcdef20000032.jpg and you only want the subject code "20000032" you would use this substr: var Credit = decodeURI(selectedFile.name).substr(6, 8); If your filenames have a variable number of characters or the file extensions are not always 3 characters, then it will be harder, but not too hard.
... View more
‎May 15, 2021
04:09 PM
@Jörn5F90 can you give us an exampe filename and the desired value you want written to SubjectCode?
... View more
‎May 07, 2021
02:27 PM
This is what I have working. Sorry for the long sparql // variable for the query results
var reply = "";
// create a new websocket object
var http = new Socket();
// open the TCP web socket
if (http.open ("vocab.getty.edu:80", "UTF-8")) {
// example search string entered by user
var searchStringEntered = " Musée d'Orsay";
// clean search text: remove leading and trailing spaces; remove symbols; insert +AND+
var searchStringClean = searchStringEntered.replace(/^\s+|\s+$/g,'').replace(/[|;$%@<>."]/g, "")
var searchString = searchStringClean.replace(/[ +&]/g, "+AND+")
searchString = encodeURI(searchString)
// sparql query
http.write ("GET "+"http://vocab.getty.edu/sparql.json?query=SELECT+%3FSubject+%3FprefName+%3Fdisplay+%3FindexName+%3FdisplayName+%3Fbio+%3Fplace+%3FplaceSubject+%3FplaceLabel+%3FplaceParentString+%3Flat+%3Flong+%3FscopeNote+%7B%0D%0A%3FSubject+skos%3AinScheme+ulan%3A%3B+luc%3Aterm+%22"+searchString+"%22%3B+gvp%3AprefLabelGVP+%5Bxl%3AliteralForm+%3FprefName%5D.%0D%0AOPTIONAL+%7B%3FSubject+xl%3AaltLabel+%5Bxl%3AliteralForm+%3FindexName%3B+gvp%3AtermDisplay+%3Findex%5D%3B+FILTER+%28+%3Findex+%3D+%3Chttp%3A%2F%2Fvocab.getty.edu%2Fterm%2Fdisplay%2FIndexing%3E+%29%7D%0D%0AOPTIONAL+%7B%3FSubject+xl%3AaltLabel+%5Bxl%3AliteralForm+%3FdisplayName%3B+gvp%3AtermDisplay+%3Fdisplay%5D%3B+FILTER+%28+%3Fdisplay+%3D+%3Chttp%3A%2F%2Fvocab.getty.edu%2Fterm%2Fdisplay%2FDisplay%3E+%29%7D%0D%0AOPTIONAL+%7B%3FSubject+foaf%3Afocus%2Fgvp%3AbiographyPreferred%2Fschema%3Adescription+%3Fbio%7D++%0D%0AOPTIONAL+%7B%3FSubject+foaf%3Afocus%2F+bio%3Aevent+%5Bdct%3Atype+%5Brdfs%3Alabel+%22location+%28activity+or+state%29%22%40en%5D%3B+schema%3Alocation+%3Fplace%5D.%0D%0A%3FplaceSubject+foaf%3Afocus+%3Fplace%3B+%0D%0Agvp%3AprefLabelGVP+%5Bxl%3AliteralForm+%3FplaceLabel%5D%3B%0D%0Agvp%3AparentString+%3FplaceParentString%3B+%0D%0Afoaf%3Afocus+%5Bwgs%3Alat+%3Flat%3B+wgs%3Along+%3Flong%3B%5D%7D+%0D%0AOPTIONAL+%7B%3FSubject+skos%3AscopeNote+%5Bdct%3Alanguage+gvp_lang%3Aen%3B+rdf%3Avalue+%3FscopeNote%5D%7D%0D%0A%7Dorder+by+%3FprefName&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql "+
"HTTP/1.0\r\n"+
"Accept: text/html,charset/utf-8,application/sparql-results+json\r\n"+
"Connection: close\r\n\r\n");
// send the request (set a long timeout)
reply = http.read(99999999);
$.writeln(reply)
// close the socket
http.close();
};
... View more
‎May 07, 2021
01:40 PM
1 Upvote
I hesitate to post this because Adobe might break it or remove it, but I discovered that the Socket Object still exists Socket object
I tried socket in the past but I found webaccesslib to be easier and to have more options, so I forgot about it. After some tinkering, I got socket and GET to work for my sparql queries.
... View more
‎May 06, 2021
08:22 AM
Thanks for the info, I'll give it a try.
... View more
‎May 04, 2021
12:42 PM
1 Upvote
Agreed. I am lost on how to use libCurl or openSSL with a Bridge script. And to the Bridge Team: I wasn't just playing around with Webaccesslib, I now have users who are angry that my script is broken.
... View more
‎Oct 22, 2019
09:25 AM
1 Upvote
Carmel - have you made progress on creating a custom metadata panel? The current way to do this is documented in XMP Metadata UI SDK CC 2014 In the doc folder, look at XMPMetadataUI.pdf for details. You can start with their sample extention and customize for your needs. Also, you can create your own namespace for custom properties, in case no other namespaces are appropriate. On thing to know is that there is a bug with the extensions which causes invalid XMP arrays to be generated. Becasue of this, you should only use XMP text properties, not bag, seq, or langAlt. Let me know if you need help.
... View more
‎Jan 21, 2019
09:56 AM
2 Upvotes
Sarah, I think you are using the wrong variable name Filename, when it should be FileName, e.g., var CommunityType = FileName.slice(0,4) I changed these in your code and it works for me now. #target bridge if( BridgeTalk.appName == "bridge" ) { FT = MenuElement.create("command", "Convert FileName to Title", "at the end of Tools"); } FT.onSelect = function () { var thumbs = app.document.selections; if(!thumbs.length) return; if (ExternalObject.AdobeXMPScript == undefined) ExternalObject.AdobeXMPScript = new ExternalObject("lib:AdobeXMPScript"); for(var a in thumbs){ var selectedFile = thumbs.spec; var FileName = decodeURI(selectedFile.name).slice(0,7) var myXmpFile = new XMPFile( selectedFile.fsName, XMPConst.UNKNOWN, XMPConst.OPEN_FOR_UPDATE); var myXmp = myXmpFile.getXMP(); var CommunityType = FileName.slice(0,4) switch (CommunityType) { case 'SCRB': CommunityType = "Northern Coastal Scrub:"; break; case 'CLOW': CommunityType = "Coast Live Oak Woodlands:" } var Plot = FileName.slice(5,6) var Transect = FileName.slice(7) var NewFileName = CommunityType + " Plot " + Plot + ", Transect " + Transect var Desc=[]; var count = myXmp.countArrayItems(XMPConst.NS_DC, "title"); for(var i = 1;i <= count;i++){ Desc.push(myXmp.getArrayItem(XMPConst.NS_DC, "title", i)); } Desc=Desc.toString() + " " + NewFileName; myXmp.deleteProperty(XMPConst.NS_DC, "title"); myXmp.appendArrayItem(XMPConst.NS_DC, "title", Desc, 0, XMPConst.ALIAS_TO_ALT_TEXT); myXmp.setQualifier(XMPConst.NS_DC, "title[1]", "http://www.w3.org/XML/1998/namespace", "lang", "x-default"); if (myXmpFile.canPutXMP(myXmp)) { myXmpFile.putXMP(myXmp); myXmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY); } } }
... View more
‎Oct 17, 2018
08:50 PM
pdophoto​ It has something to do with using a dialog window. I changed your code to a palette and now when Apply() runs, the new data appears in the side panel immediately. var p = new Window ("palette", "My Metas", undefined); You also have to add a close function to the "OK" button": pg1pg25.b2 = pg1pg25.add("button", undefined, "OK"); pg1pg25.b2.onClick = function(){ p.close(); };
... View more
‎Oct 17, 2018
07:21 PM
pdophoto​ I noticed it today on another panel I was working on. I will investigate more and if I can't find a solution I will report it to Adobe as a bug.
... View more
‎Oct 17, 2018
11:49 AM
kznhpim41127825​ Yes, I have made a working side and info panel, but there is still a bug where metadata structures are not saved correctly (see above posts). If you are only using custom flat text properties, the panels seem to work.
... View more
‎Oct 11, 2018
01:50 PM
1 Upvote
pdophoto​ A suggestion: It might be good to indicate when a new edit has been made to a field. For example, I edit Title then click the radiobutton to save it, then I realize I made a mistake and need to change the Title again, I need to click the radio button again to save, but I might not realize this if the radiobutton is already selected. My idea is: if the field is edited, the radiobutton will be de-selected, indicating it has not been saved yet. For example, change this: pg1pg2a.et.onChanging = function () {myTitle = pg1pg2a.et.text;}; To this: pg1pg2a.et.onChanging = function () {myTitle = pg1pg2a.et.text; pg1pg2a.ut.value = false;};
... View more
‎Oct 11, 2018
12:18 PM
Hi pdophoto​ Your panel is working great on Windows. It looks good and has a lot of useful information. I found a problem with Keywords though. When it writes new keywords, it is not separating them into separate bag items. It is writing all of them into one value, so you get "keyword1,keyword2,keyword3" instead of: keyword1 keyword2 keyword3 On row 239, replace this: xmp.setProperty(XMPConst.NS_DC, "subject", mySubject); with this: // split edittext value into an array - splitting on comma in this example var separatedBagItems = mySubject.split(','); // write the new data as a Bag array xmp.appendArrayItem (XMPConst.NS_DC,"subject", "", 0, XMPConst.ARRAY_IS_UNORDERED); for (var i = 1; i < (separatedBagItems.length + 1); i++){ xmp.setProperty (XMPConst.NS_DC,"subject"+"[" + i + "]", separatedBagItems[i - 1]); }
... View more
‎Oct 10, 2018
03:45 PM
pdophoto​ $.writeln() in your script might be forcing ExtendScript toolkit to open when it is run in Bridge from the Startup Scripts folder.
... View more
‎May 07, 2018
09:55 AM
2 Upvotes
I can share several different panels. The code might require some explanation, so we could start a conversation off this list, if that would be more appropriate. The one I made for pdophoto uses a dictionary to define UI fields and XMP read/write. It is an idea I have to make a base code that is easily customizable. The 'easily' part is not quite ready yet. It is very much a work in progress, but it might help. I have not completed all the special functions needed to make pdophoto's fields work - lots of work left to do. To run it, place it in your Startup Scripts, restart Bridge, then look for the new "Metadata" menu at top of the Bridge window (next to "Help") pdophoto_2018-05-07.jsx - Google Docs I also created a custom panel with a different approach for IPTC Cultural Heritage metadata. It has some custom functions for data validation, such as dates, and dropdowns, that might be helpful. It also includes a batch import/export tool. https://iptc.org/std/photometadata/tools/IPTC_Cultural_Heritage_Panel.zip Another complex panel for Artworks can be downoaded at Metadata Deluxe / VRA Bridge Metadata Tools There are many things to know when you make a JavaScript panel. You are basically handling all the read\write functions from scratch. This means some things Bridge handles, you have to code. An example is the label "(multiple values)" that you see when several files are selected but do not share the same metadata. I have done this in my code and I think it works, but it can be tricky. Anyone is free to reuse my code and I can help answer any questions, either here or by private message.
... View more
‎May 06, 2018
04:37 PM
1 Upvote
pdophoto - I was able to create CC2018 Metadata Extension using some of the Exif fields you need. More testing would be needed on the remaining fields in your custom panel, but we already know about the bugs mentioned earlier in this conversation. However, I discovered a few things: The side metadata panel still cannot create structures, so it is not safe to use IPTC fields like Title, Creator, Description, Keywords. Exif, and other, camera fields can be made editable in a custom extension, but some of them do not save to XMP. For example, Flash is a structure of several properties and does not seem to save correctly when entered in a custom panel. The extension also produces an info panel, but all camera fields are not editable, so it will not help you. I also looked into making a JavaScript (ScriptUI) panel, which looks like this: There are several things to consider about this approach: Creating a panel (palette window) that remains open and refreshes as you navigate files, is not too hard. Some fields are stored in XMP in a form that is not easy to read, such as F Number. These need to be converted into a form that you are accustomed to seeing in Bridge (F Number "4/1" = "F/4.0"). JavaScript functions can be written to do this, but it will require understanding the conversions and some programming skill. I did not pursue this further, but can help you if you are interested. I can share the code for both examples about, if you are interested.
... View more
‎May 04, 2018
01:01 PM
1 Upvote
Have you considered building a custom panel in JavaScript (Adobe ScriptUI)? I hesitate to mention it because it has it's own set of bugs (mostly UI style things like text color and size), but you can make some very useful metadata panels with it. Also, JavaScript plugins are much easier to install - just drop a single .jsx file in StartupScripts. See the Bridge CC 2018 SDK at Adobe I/O Console Look in the docs folder for Bridge CC 2018 JavaScript Guide.pdf and Bridge CC 2018 JavaScript Reference.pdf Creating a JavaScript panel requires some coding ability, but it's easier than CEP. Yes, the way forward is CEP, but until we get some better examples and/or tools, JavaScript plugins are much more practical.
... View more
‎Apr 24, 2018
08:30 AM
I have many custom panels I would like to convert to CEP. Creating the UI in CEP seems straightforward (nice to be able to use html and css for styling), but so far I have not been able to read or write XMP. If I make any progress, I'll let you know.
... View more
- « Previous
- Next »