Copy link to clipboard
Copied
Hey!
Does anyone have an existing script for converting all notes/annotations to text layers?
It can be all notes to a single text layer or multiple.
I currently have a script to select all text layers, send them to a group, search their contents for keywords, and create a txt file if they contain the keywords. I am looking to add a snippet of code to the top of this script in order to cover the off chance a note/annotation was used instead of a text layer.
Looking through the Adobe Javascript Ref 2020 document, I did not see anything in the native DOM for adobe, so I am assuming this will be an AM event.
If it helps, here is the code for creating a note I copied from ScriptListener/Clean SL.
select3(true, true);
function select3(dontRecord, forceNotify) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var reference = new ActionReference();
reference.putClass( s2t( "textAnnotTool" ));
descriptor.putReference( c2t( "null" ), reference );
descriptor.putBoolean( s2t( "dontRecord" ), dontRecord );
descriptor.putBoolean( s2t( "forceNotify" ), forceNotify );
executeAction( s2t( "select" ), descriptor, DialogModes.NO );
}
// =======================================================
historyStateChanged2(645, "New Note", true, 2);
function historyStateChanged2(ID, name2, hasEnglish, itemIndex) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putInteger( s2t( "documentID" ), 621 );
descriptor.putInteger( s2t( "ID" ), ID );
descriptor.putString( s2t( "name" ), name2 );
descriptor.putBoolean( s2t( "hasEnglish" ), hasEnglish );
descriptor.putInteger( s2t( "itemIndex" ), itemIndex );
executeAction( s2t( "historyStateChanged" ), descriptor, DialogModes.NO );
}
// =======================================================
make(521, 659, 240, 140);
function make(horizontal, vertical, horizontal2, vertical2) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var descriptor3 = new ActionDescriptor();
var descriptor4 = new ActionDescriptor();
var reference = new ActionReference();
reference.putClass( s2t( "annotation" ));
descriptor.putReference( c2t( "null" ), reference );
descriptor3.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal );
descriptor3.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical );
descriptor2.putObject( s2t( "location" ), c2t( "Pnt " ), descriptor3 );
descriptor4.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal2 );
descriptor4.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical2 );
descriptor2.putObject( s2t( "size" ), s2t( "offset" ), descriptor4 );
descriptor2.putEnumerated( s2t( "annotType" ), s2t( "annotType" ), s2t( "annotText" ));
descriptor.putObject( s2t( "using" ), s2t( "annotation" ), descriptor2 );
executeAction( s2t( "make" ), descriptor, DialogModes.NO );
}
// =======================================================
historyStateChanged3(646, "Edit Note", true, 3);
function historyStateChanged3(ID, name2, hasEnglish, itemIndex) {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
descriptor.putInteger( s2t( "documentID" ), 621 );
descriptor.putInteger( s2t( "ID" ), ID );
descriptor.putString( s2t( "name" ), name2 );
descriptor.putBoolean( s2t( "hasEnglish" ), hasEnglish );
descriptor.putInteger( s2t( "itemIndex" ), itemIndex );
executeAction( s2t( "historyStateChanged" ), descriptor, DialogModes.NO );
}
// =======================================================
set("TEXT\r");
function set(text) {
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putIndex( s2t( "annotation" ), 0 );
descriptor.putReference( c2t( "null" ), reference );
descriptor2.putData( s2t( "textData" ), String.fromCharCode( 255, 254, 84, 0, 69, 0, 88, 0, 84, 0, 13, 0 ) );
descriptor2.putString( s2t( "text" ), text );
descriptor.putObject( s2t( "to" ), s2t( "annotation" ), descriptor2 );
executeAction( s2t( "set" ), descriptor, DialogModes.NO );
}
@c.pfaffenbichler, that's right - we can't access notes content by DOM or AM, but we know that they are stored in an image file (i rarely work with binary data and admit that not all things in the code are perfect, but it seems to work)
#target photoshop
var s2t = stringIDToTypeID,
doc = new AM(),
f = new File(Folder.temp.fsName + "/" + "annotations.psd");
if (doc.checkNotes()) {
doc.duplicate('annotations', true);
doc.setImageSize(1);
activeDocument.xmpMetadata.rawData = '';...
Copy link to clipboard
Copied
Seems deafult-Scripting-access for notes is limited.
Copy link to clipboard
Copied
@c.pfaffenbichler, that's right - we can't access notes content by DOM or AM, but we know that they are stored in an image file (i rarely work with binary data and admit that not all things in the code are perfect, but it seems to work)
#target photoshop
var s2t = stringIDToTypeID,
doc = new AM(),
f = new File(Folder.temp.fsName + "/" + "annotations.psd");
if (doc.checkNotes()) {
doc.duplicate('annotations', true);
doc.setImageSize(1);
activeDocument.xmpMetadata.rawData = '';
doc.saveAs(f);
doc.closeDocument();
if (f) {
f.open("r");
f.encoding = "BINARY";
var s = f.read();
f.close();
f.remove();
i = s.indexOf('8BIMAnno')
if (i) {
var blockLength = hextoDec(toHex(s, i + 8, 4)),
annotations = [];
s = s.substr(i + 12, blockLength);
do {
var i = s.indexOf('txtC');
if (i >= 0) {
blockLength = hextoDec(toHex(s, i + 4, 4)) - 2;
s = s.substr(i + 10);
if (blockLength) {
var content = '';
do {
content += String.fromCharCode(hextoDec(toHex(s, 0, 2)))
blockLength -= 2
s = s.substr(2)
} while (blockLength)
annotations.push(content);
}
} else break;
} while (true)
for (var i = 0; i < annotations.length; i++) {
activeDocument.artLayers.add()
activeDocument.activeLayer.kind = LayerKind.TEXT
activeDocument.activeLayer.textItem.contents = annotations[i]
}
}
}
}
function toHex(s, from, bits) {
s = s.substr(from, bits);
var h = '';
for (var i = 0; i < bits; i++) h += (('0' + s.charCodeAt(i).toString(16)).slice(-2));
return h
}
function hextoDec(val) {
var hex = val.split('').reverse().join(''),
dec = 0;
for (var i = 0; i < hex.length; i++) {
dec += parseInt(hex[i], 16) * Math.pow(16, i);
}
return dec;
}
function AM() {
var s2t = stringIDToTypeID;
this.checkNotes = function () {
try {
(r = new ActionReference()).putEnumerated(s2t('annotation'), s2t('ordinal'), s2t('targetEnum'));
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('delete'), d, DialogModes.NO);
(r = new ActionReference()).putEnumerated(s2t('historyState'), s2t('ordinal'), s2t('previous'));
(d = new ActionDescriptor()).putReference(s2t('null'), r);
executeAction(s2t('select'), d, DialogModes.NO)
return true
} catch (e) {
return false
}
}
this.duplicate = function (title, merged) {
(r = new ActionReference()).putEnumerated(s2t("document"), s2t("ordinal"), s2t("targetEnum"));
(d = new ActionDescriptor()).putReference(s2t("target"), r);
d.putString(s2t("name"), title);
if (merged) d.putBoolean(s2t("merged"), merged);
executeAction(s2t("duplicate"), d, DialogModes.NO);
}
this.setImageSize = function (width) {
(d = new ActionDescriptor()).putUnitDouble(s2t("width"), s2t("pixelsUnit"), width);
d.putBoolean(s2t("constrainProportions"), true);
d.putEnumerated(s2t("interpolation"), s2t("interpolationType"), s2t("bilinear"));
executeAction(s2t("imageSize"), d, DialogModes.NO);
}
this.saveAs = function (pth) {
(d = new ActionDescriptor());
(d1 = new ActionDescriptor()).putObject(s2t("as"), s2t("photoshop35Format"), d);
d1.putPath(s2t("in"), pth);
d1.putBoolean(s2t("embedProfiles"), false);
executeAction(s2t("save"), d1, DialogModes.NO);
}
this.closeDocument = function () {
(d = new ActionDescriptor()).putEnumerated(s2t('saving'), s2t('yesNo'), s2t('no'));
executeAction(s2t('close'), d, DialogModes.NO)
}
}
Copy link to clipboard
Copied
Thanks for the insight!
Hopefully the original poster will drop by to acknowledge your effort.
Copy link to clipboard
Copied
This is awesome thank you!
Copy link to clipboard
Copied
If it solves your issue remember to mark @jazz-y ’s post as »correct answer«.
Edit: I apologize, I had missed that it is already marked as »correct answer«.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more