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

Creating a note/annotation in Photoshop

Community Beginner ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

I am working on a script that needs to be run on every file I work with.  I have an action that does what I need it to, however I would like a way to document in the photoshop file that the action has been run.  Since the action might need to be done multiple times per file, it would be ideal if the note would store some information so for future reference I can see what folders the action has been run on and how many times the action has been run.

The action works just fine, I know how to make the action call up the script I need.  I can create all the variables I need to fill the note with the information I want.  I just cant find the script for creating a note/annotation and filling the note with the desired text.

Is this even possible?

TOPICS
Actions and scripting

Views

5.3K

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
LEGEND ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

Do you need metadata information separate for every file (stored in these certain files), or you need one other text file where are gathered informations about all processed files? So one note per each file nested in their metadas, or one note for all files saved somewhere on disk?

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
Community Beginner ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

creating a note in the photoshop file using the note tool would be ideal.  Current work around I have going is  just making a new text layer with the information I need and hiding it at the bottom of the file. 

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
LEGEND ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

Recently I have read something that placing (or reading or both) notes is not scriptable, however Mike Hall found some way to do it, but I didn't focus deeply on his workaround and now I don't remember where I have seen it. Later i'll check it, what way that could be done (if I find it, but probably that had something to do with Extensible Metadata Platform).

Do you use Adobe Bridge? There you have Labels (5 colours) and Ratings (up to 5). They can be used to inform you about specific information for you. They would be more like symbols you undrstand your way. As workaround also file names can be changed like from someName.psd to someName_10.jpg what means this file was processed 10 times.

Just in case that wasn't possible you ask for, list all info you need to store in notes (times something happened, processed folders, ???), maybe they can be displayed other way, not by those notes but other depending what kind of info they are...

I never used annotation, but now I checked ScriptListener records them, so maybe there is a chance to do what you wish...

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
Community Expert ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

Hi

how about this

///////////////////////////////////////////////////////////////////////////////////

// Create a new note at position x,y

///////////////////////////////////////////////////////////////////////////////////

function makeAnnotation(posX,posY) {

  function cTID(s) { return app.charIDToTypeID(s); };

  function sTID(s) { return app.stringIDToTypeID(s); };

    var desc30 = new ActionDescriptor();

        var ref12 = new ActionReference();

        ref12.putClass( sTID('annotation') );

    desc30.putReference( cTID('null'), ref12 );

        var desc31 = new ActionDescriptor();

            var desc32 = new ActionDescriptor();

            desc32.putUnitDouble( cTID('Hrzn'), cTID('#Pxl'), posX );

            desc32.putUnitDouble( cTID('Vrtc'), cTID('#Pxl'), posY );

        desc31.putObject( cTID('Lctn'), cTID('Pnt '), desc32 );

            var desc33 = new ActionDescriptor();

            desc33.putUnitDouble( cTID('Hrzn'), cTID('#Pxl'), 240.000000 );

            desc33.putUnitDouble( cTID('Vrtc'), cTID('#Pxl'), 140.000000 );

        desc31.putObject( cTID('Sz  '), cTID('Ofst'), desc33 );

        desc31.putEnumerated( sTID('annotType'), sTID('annotType'), sTID('annotText') );

    desc30.putObject( cTID('Usng'), sTID('annotation'), desc31 );

    executeAction( cTID('Mk  '), desc30, DialogModes.NO );

};

and this

///////////////////////////////////////////////////////////////////////////////////

// Insert text in this created note

///////////////////////////////////////////////////////////////////////////////////

var idsetd = charIDToTypeID( "setd" );

    var desc58 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref12 = new ActionReference();

        var idannotation = stringIDToTypeID( "annotation" );

        ref12.putIndex( idannotation, 0 ); // the number/index of note

    desc58.putReference( idnull, ref12 );

    var idT = charIDToTypeID( "T   " );

        var desc59 = new ActionDescriptor();

        var idTxtD = charIDToTypeID( "TxtD" );

        desc59.putData( idTxtD, String.fromCharCode( 255, 254, 116, 0, 104, 0, 105, 0, 115, 0, 32, 0, 105, 0, 115, 0, 32, 0, 116, 0, 101, 0, 120, 0, 116, 0, 32, 0, 105, 0, 110, 0,

32, 0, 97, 0, 32, 0, 110, 0, 111, 0, 116, 0, 101, 0 ) );

        var idtext = stringIDToTypeID( "text" );

        desc59.putString( idtext, """this is text in a note""" );

    var idannotation = stringIDToTypeID( "annotation" );

    desc58.putObject( idT, idannotation, desc59 );

executeAction( idsetd, desc58, DialogModes.NO );

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
LEGEND ,
Dec 21, 2017 Dec 21, 2017

Copy link to clipboard

Copied

MFreemanRKS, you find an answer in created by you Create notes/annotations? - PS-SCRIPTS.COM​ topic on that forum.

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
Community Beginner ,
Jan 02, 2018 Jan 02, 2018

Copy link to clipboard

Copied

The script from there is actually really close to what I need.  The only thing that I am having problems with is this script deletes the notes that are already in the file.   Where in that script are you adding the information "# and working"  into the note?

Thank You!

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
LEGEND ,
Feb 11, 2018 Feb 11, 2018

Copy link to clipboard

Copied

LATEST

I will look into it today to see what I can do, as that was some time ago I wrote it and not remember well how that worked.

EDIT:

Another first of this kind script you will not find other like it on this and Create notes/annotations? - PS-SCRIPTS.COM forums (and probably nowhere ). It works extremaly fast with even many channels, paths and layer(Set)s beside notes. Only first time it takes 1/5 second while every next just 100 ms (40 for saving, 25 reading, and 20 for searching by RegEx).

For those who didn't read earlier posts: you can record this script as last item of your action. It's going to create 'note' with number of times a file was processed and name of its parent folder (remove .name in aD.path.name if you want full path).

$.level = 0; try {

     pth = (aD = activeDocument).path; function sTT(v) {return stringIDToTypeID(v)}

     with(psd = new PhotoshopSaveOptions()) {

          annotations = !(alphaChannels = embedColorProfile = layers = spotColors = false)

     }

     aD.saveAs(fle = File('~/desktop/.psd'), psd, true)

     function anno() {

          fle.open('r'); var r = fle.read(); fle.close(), fle.remove()

          var r = r.match(/txtC.{3,6}(\n.{2})?((?:\x00.)+)?/g)

          if (r) {for(i = 0; i < l = r.length; i++) {

               if (n = r.slice(10, i == l - 1 ? r.length : -4).match(/[^\x00]/g))

               {if (/#\d+/.test(n = n.join(''))) return parseFloat(n.slice(1)) + 1}

          }}

     }

     if (arr = ['horizontal', 'vertical'], !(n = anno())) {

          (ref1 = new ActionReference()).putClass(sTT('annotation'));

          (dsc1 = new ActionDescriptor()).putReference(sTT('null'), ref1)

          u = (p = preferences).rulerUnits, p.rulerUnits = Units.PIXELS

          for(dsc3 = new ActionDescriptor(), j = 0; j < arr.length; j++) {

               dsc3.putUnitDouble(sTT(arr), sTT('pixelsUnit'),

               eval('aD.' + (!j ? 'width' : 'height') +'.value * 19 / 20'))

          } p.rulerUnits = u;

          (dsc2 = new ActionDescriptor()).putObject(sTT('location'), sTT('paint'), dsc3)

          dsc2.putEnumerated(aT = sTT('annotType'), aT, sTT('annotText')), dsc1.putObject

          (sTT('using'), sTT('annotation'), dsc2), executeAction(sTT('make'), dsc1, DialogModes.NO);

     }

     number = '#' + (n || 0) + ' & ' + pth.name;

     (ref1 = new ActionReference()).putIndex(sTT('annotation'), i); (dsc1 = new ActionDescriptor())

     .putReference(sTT('null'), ref1); (dsc2 = new ActionDescriptor()).putString(sTT('text'), number)

     dsc1.putObject(sTT('to'), sTT('annotation'), dsc2), executeAction(sTT('set'), dsc1, DialogModes.NO)

}

catch (err) {alert(err.message)}

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
Enthusiast ,
Dec 20, 2017 Dec 20, 2017

Copy link to clipboard

Copied

Is there way, how to read annotations?

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
Enthusiast ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

Until now, I couldn't find a way of read annotations. Only deleting and creating them.

Although, the annotation can be passed to a photoshop PDF and converted in the PDF localized notes! This means there is a way of retrieving the annotations content but on an another level that is not scripting.

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
People's Champ ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

Hacker way )

When the file is saved (if the anotations changed you need to save the file, you do not need to close it), you can open the binary document file through the script and find the "8BIMAnno" tag. After it you will find the structure from which you can pull out the number of annotations, and by the tags "txtC" and "txtA" pull out the text and the author of the annotations.

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
People's Champ ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

Very simplistic but working example )

var file = new File(app.activeDocument.fullName);

file.open("r");

file.encoding = "BINARY";

if (file.error) { alert(file.error); executeAction( stringIDToTypeID( "stop" ), undefined, DialogModes.NO ); }

var block_size = 10000;

var len = file.length/block_size;

for (var i = 0; i < len; i++)

    {

    var buff = file.read(block_size);

    var n = buff.indexOf("8BIMAnno");

    if (n >= 0)

        {

        var s = buff.substr(n)

        var n = s.indexOf("txtC");

        if (n >= 0)

            {

            s = s.substr(n+10);

            var txt = "";

            for (var x = 0; x < 200; x+=2)

                {

                txt += String.fromCharCode(256*s.charCodeAt(x) + s.charCodeAt(x+1));

                }

           

            alert("Found annotation:\n\n" + txt);   

            break;

            }

        }

    }

file.close();

alert("Done")

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
LEGEND ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

It works however when I run it from ExtendScript ToolKit it doesn't finish its work after 'Done' is alerted. ESKT gets frozen. Blue stop icon is still active, but can not be used to stop the script. Only closing ESKT helps. And btw there are added four chinese letters to end of annotation.

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
People's Champ ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

The length of the text is in the next 4 bytes after the txtC tag. I'm too lazy to write a full code. It's just an idea that I myself do not need. )

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
Enthusiast ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

Parsing file like this easy to write but bad thing may happen.

You should first to read lenght of PSD header then length of subsection and so on and pick only needed data instead parsing all.

Adobe Photoshop File Formats Specification

Check xbytor script which reads actions files and can convert them into XML ect.

There are methods for reading binary files.

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
Community Expert ,
Dec 22, 2017 Dec 22, 2017

Copy link to clipboard

Copied

What about storing the information you want in a custom metadata field that can either be read by another script, creating a custom metadata panel, or by looking at the raw file data?

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
Community Beginner ,
Jan 02, 2018 Jan 02, 2018

Copy link to clipboard

Copied

sorry about radio silence, been on vacation from work.  I am looking into all of your responses.  Thank you so much for all of your help thus far, I'm sure something in here will do what I need!

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