Search code examples
javascriptjavascript-objectsphotoshopphotoshop-script

Build a photoshop script to add a text layer to the batch of photos


Note : My photoshop is cs6
I am ordered to create a script that works on bunch of photo and add a text for every single photo.

I have a data like this (text list notepad example) : 'logo file'
'model number'
'model number'

logo accuride.jpg
acc-899
acc-567
acc-776
logo bocsh.jpg
boc-777
boc-699
boc-563
logo dell.jpg
65777
89992
45663

Basically, I already imagine the step :
1. Locate where the notepad (the list)
2. Read and Parse the list. To know what logo and what to write
3. Took a photo on library (ie. logo accuride.jpg)
4. Put in the active document layer
5. Create new text layer, place on top of the logo
6. Export as jpg, rename as same as model number
7. delete all layer or close the document
8. repeat from step 1

from this
to this - goal

Here is what i have done :

var doc = activeDocument  
var textFile = new File(Folder.desktop+ '/model-number.txt');  
var list = readText (textFile).split('\n'); 

 for (var j = 0; i<list.length; i++) {
     if (list[j].some("logo")) { //jika list j contain kata "logo" maka :

        var artLayerRef = doc.artLayers.add()  
        artLayerRef.kind = LayerKind.TEXT;  
        var textItemRef = artLayerRef.textItem;  
        textItemRef.contents = list[i]  
     }
 }

 function readText(file){  
     if (textFile.exists) {  
    textFile.encoding = "ANSI";  
    textFile.lineFeed = "unix";  
    textFile.open("r", "TEXT", "????");  
    var str = textFile.read();  
    textFile.close();  
    return str;  
    }  
}  

And the truth is, i am very newbie with this js, especially for photoshop scripting. Usually I am create a vba script to support my collage.
I spend more than 2 hour ONLY to figure how to import image into an active document layer and still no luck.
I also imagine to use vba to call photoshop application. So the data came from table on my workbook. But now, only to import an image makes me dizzy.

I forgot to ask :
1. How do I import an image into a layer of active document?
2. How to check substring from array of string in js? Like when i found word "logo*" then do if statement.

I am very appreciate any solution, assistance and help from you.
Thanks.

Yuri


Solution

  • There's a Photoshop plugin called ScriptListener, after you install it, Photoshop will start to write most of the actions you do in Photoshop as Action Manager Javascript Code. That's one of the ways to find code for things you can't find in the Scripting References pdf. For example to import an image, you can do File > Place Embedded, load a selection to determine its bounding box, crop to this selection and deselect. These actions will give you this code in ScriptingListenerJS.log on your desktop:

    // =======================================================
    var idPlc = charIDToTypeID( "Plc " );
        var desc7 = new ActionDescriptor();
        var idIdnt = charIDToTypeID( "Idnt" );
        desc7.putInteger( idIdnt, 12 );
        var idnull = charIDToTypeID( "null" );
        desc7.putPath( idnull, new File( "/C/Users/Sergey Kritskiy/Desktop/temp/triangles.png" ) );
        var idFTcs = charIDToTypeID( "FTcs" );
        var idQCSt = charIDToTypeID( "QCSt" );
        var idQcsa = charIDToTypeID( "Qcsa" );
        desc7.putEnumerated( idFTcs, idQCSt, idQcsa );
        var idOfst = charIDToTypeID( "Ofst" );
            var desc8 = new ActionDescriptor();
            var idHrzn = charIDToTypeID( "Hrzn" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc8.putUnitDouble( idHrzn, idPxl, 0.000000 );
            var idVrtc = charIDToTypeID( "Vrtc" );
            var idPxl = charIDToTypeID( "#Pxl" );
            desc8.putUnitDouble( idVrtc, idPxl, 0.000000 );
        var idOfst = charIDToTypeID( "Ofst" );
        desc7.putObject( idOfst, idOfst, desc8 );
    executeAction( idPlc, desc7, DialogModes.NO );
    
    // =======================================================
    var idsetd = charIDToTypeID( "setd" );
        var desc9 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref1.putProperty( idChnl, idfsel );
        desc9.putReference( idnull, ref1 );
        var idT = charIDToTypeID( "T   " );
            var ref2 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idChnl = charIDToTypeID( "Chnl" );
            var idTrsp = charIDToTypeID( "Trsp" );
            ref2.putEnumerated( idChnl, idChnl, idTrsp );
        desc9.putReference( idT, ref2 );
    executeAction( idsetd, desc9, DialogModes.NO );
    
    // =======================================================
    var idCrop = charIDToTypeID( "Crop" );
        var desc11 = new ActionDescriptor();
        var idDlt = charIDToTypeID( "Dlt " );
        desc11.putBoolean( idDlt, true );
    executeAction( idCrop, desc11, DialogModes.NO );
    
    // =======================================================
    var idsetd = charIDToTypeID( "setd" );
        var desc13 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref3 = new ActionReference();
            var idChnl = charIDToTypeID( "Chnl" );
            var idfsel = charIDToTypeID( "fsel" );
            ref3.putProperty( idChnl, idfsel );
        desc13.putReference( idnull, ref3 );
        var idT = charIDToTypeID( "T   " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idNone = charIDToTypeID( "None" );
        desc13.putEnumerated( idT, idOrdn, idNone );
    executeAction( idsetd, desc13, DialogModes.NO );
    

    It's quite hard to read, there're utilities that help to beautify it a little bit (like SLCFix.js in xbytor's xtools), but it does the job and you can see the strings you need to replace to put make a function that'd place a file in a document.

    2) for your strings and logos, I guess there're different ways of doing this, I'd do it like this:

    var list = readText(textFile).split('\n'),
        curLogo = "",
        logos = {};
    
    for (var i = 0; i < list.length; i++)
    {
        var curLine = list[i].match(/logo.*\.jpg/);
        if (curLine != null)
        {
            curLogo = list[i];
            logos[curLogo] = [];
        }
        else
        {
            logos[curLogo].push(list[i])
        }
    }
    

    this will give you an object like this which you can use later

    // {
    //     "logo accuride.jpg": [
    //         "acc-899",
    //         "acc-567",
    //         "acc-776"
    //     ],
    //     "logo bocsh.jpg": [
    //         "boc-777",
    //         "boc-699",
    //         "boc-563"
    //     ],
    //     "logo dell.jpg": [
    //         "65777",
    //         "89992",
    //         "45663"
    //     ]
    // }
    
    for (var logo in logos)
    {
        $.writeln(logo) // logo accuride.jpg
        $.writeln(logos[logo].length) // 3
    }