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

Writing an applescript to import text to text layer

Community Beginner ,
Sep 15, 2019 Sep 15, 2019

Copy link to clipboard

Copied

Hi all

Is there an easy way to write an AppleScript that would do this:

From an open PS document.
1) Go to a specified txt document.
2)  Copy the first line
3) Paste into new text layer

4) Change name of text layer to a specified value
5)  Duplicate document and name with the text from layer
6) Save as 
7) Go back to original document and repeat until reaching the end of the lines in the document.

There's a tutorial on youtube using Java and JSON, but I'd like to avoid Java if I can.

TOPICS
Actions and scripting

Views

3.8K

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
Community Expert ,
Sep 15, 2019 Sep 15, 2019

Copy link to clipboard

Copied

Is there a reason you want to use apple script? More people know extendscript and can offer more help. Your requirements look fairly straightforward though and should be able to be 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
Community Beginner ,
Sep 15, 2019 Sep 15, 2019

Copy link to clipboard

Copied

Hi Chuck

I'm willing to learn ExtendScript.

Just want to avoid Java

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 ,
Sep 15, 2019 Sep 15, 2019

Copy link to clipboard

Copied

What does the text document consist of? How are the lines separeted: periods, commas, line breaks, etc. What is the naming convention for the layers?

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 ,
Sep 15, 2019 Sep 15, 2019

Copy link to clipboard

Copied

The line consist of 1 - 3 words.

The lines are currently separated by carriage returns but I could add commas or semi colons easily.

The text layer can be just named "text" for simplicity. They all need to be named the same for running an action on the file later.


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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Carriage returns are fine.

 

So I take it that the file needs to be saved as a psd?

 

Does your original file already have the text layer, and you just need to change the contents, or does a new text layer need to be created?

 

 

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Yes they need to be saved as psd's

Yes, changing the text in an existing text layer would be the easiest. That way it would automatically have the font, color and effects already applied. Wouldn't have to rename the type layer either. I was thinking that I would be running a batch action to set  all those on the resultant files.

So the procedure would be

1) Get line from txt

 

2) Change content of text layer 

3) Duplicate document

4) Save as psd, renaming it with the content of the text file. It can be saved in the location of the original psd.

Actually, I think that on a Mac you can still set a file as a template in file info so that the original can't be overwritten. Would that be helpful?

So, let's say I have a file with 4 lines on it.

John
Mary
Joe
George

I open my existing PSD which is a background layer and a text layer called "name". I run the script from within PS. It looks for the txt file in a specified location, copies the first line, ( to the clipboard?) selects the text layer named "name", pastes the text John, duplicates the doc, save as psd, pasting "John" from the clipboard into the file name field and close. It then goes to Mary in the txt file and repeats, then Joe, then George and then stops.

So I end up with a folder with my origianl template and 4 psd files named John, Mary, Joe and George each having the appropriate text inserted in the text layer

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Here is a script that will do what you want, I think. You need to insert the path and name of your text file, adjust whare you want the text layer, it's size, and font.

 

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('~/desktop/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder('~/desktop/Saved Files/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
    var txtInfo = readTextFile (txtFile).split('\n');
    }
else{
    run = false;
    alert('There is no text file.')
    }

if(run){
    for(var i=0;i<txtInfo.length;i++){
        dupeFile (txtInfo[i])
        var newFile = app.activeDocument;
        createTextLayer (txtInfo[i]);
        newFile.saveAs (new File(saveFolder +'/' + txtInfo[i] + '.psd'), psdOptions);
        newFile.close(SaveOptions.DONOTSAVECHANGES);
        }//end for loop
    }//end if to run

function createTextLayer(textContent){
    var artLayerRef = newFile.artLayers.add()
    artLayerRef.kind = LayerKind.TEXT;
    artLayerRef.name = 'text';
    var textItemRef = artLayerRef.textItem;
    textItemRef.justification = Justification.LEFT;
    textItemRef.size = 200;
    textItemRef.position =[20, 200];
    textItemRef.contents = textContent;
    }

function readTextFile(file){		
		file.encoding = "UTF8";
		file.lineFeed = "unix";
		file.open("r", "TEXT", "????");
		var str = file.read();
		file.close();
         return str
        }
    
function dupeFile(name){
       var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idNm = charIDToTypeID( "Nm  " );
        desc5.putString( idNm, name );//new name of file .
    executeAction( idDplc, desc5, 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
Community Beginner ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

First off, thanks very much for doing this.

 

A couple of questions.


Is this based on my first set of parameters or the later one when I realized that just changing the content of an existing text layer might be easier?

My second idea would actually be better, because I wouldn't have to run a batch action to set the text layer attributes, just manually tweek some of the font sizes if some of the text lines end up being too large for the space alotted.

Do I copy and save this as a .jsx?

I presume I can change the file paths to read from and save to an external drive. Saving to the desktop would fill the drive before all the files could be finished. I have about 3000 or so lines per txt file and there are 4 txt files to process. I'll be saving to a 12 TB RAID 5.

Thanks again

Dave


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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Yes, it would be better to use an existing text layer, where you can set the formatting and position. Then you can get rid if all that code to create and format the layer. You just need to get the layer.

 

Yes, just change the paths to there the text file is and where you want to save it. You can create a loop for multiple text 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 Beginner ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

So I would remove

function createTextLayer(textContent){
    var artLayerRef = newFile.artLayers.add()
    artLayerRef.kind = LayerKind.TEXT;
    artLayerRef.name = 'text';
    var textItemRef = artLayerRef.textItem;
    textItemRef.justification = Justification.LEFT;
    textItemRef.size = 200;
    textItemRef.position =[20, 200];
    textItemRef.contents = textContent;
    }

from your script and replace it with? Sorry for being a pain, but my last hands on coding was in BASIC on a TRS80 in high school in 1979.

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Here's the script if you already have a text layer. Just make sure the text layer name matches what the name is in the code in the getByName line. I'm assuming you want "text" as the name, so that's what it's set up for.

And, yes, you save it as a .jsx file.

 

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('~/desktop/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder('~/desktop/Saved Files/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
    var txtInfo = readTextFile (txtFile).split('\n');
    }
else{
    run = false;
    alert('There is no text file.')
    }

if(run){
    for(var i=0;i<txtInfo.length;i++){
        dupeFile (txtInfo[i])
        var newFile = app.activeDocument;
        var txtLayer = newFile.layers.getByName('text');
        txtLayer.textItem.contents = txtInfo[i];
        newFile.saveAs (new File(saveFolder +'/' + txtInfo[i] + '.psd'), psdOptions);
        newFile.close(SaveOptions.DONOTSAVECHANGES);
        }//end for loop
    }//end if to run

function readTextFile(file){		
		file.encoding = "UTF8";
		file.lineFeed = "unix";
		file.open("r", "TEXT", "????");
		var str = file.read();
		file.close();
         return str
        }
    
function dupeFile(name){
       var idDplc = charIDToTypeID( "Dplc" );
        var desc5 = new ActionDescriptor();
        var idnull = charIDToTypeID( "null" );
            var ref1 = new ActionReference();
            var idDcmn = charIDToTypeID( "Dcmn" );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idFrst = charIDToTypeID( "Frst" );
            ref1.putEnumerated( idDcmn, idOrdn, idFrst );
        desc5.putReference( idnull, ref1 );
        var idNm = charIDToTypeID( "Nm  " );
        desc5.putString( idNm, name );//new name of file .
    executeAction( idDplc, desc5, 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
Community Expert ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

I forgot to check if the text layer name changes when the new text is added. If it does, you need to add a line of code to rest the layer name:

 

TxtLayer.name = 'text';

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

So, I edited the script to put in the save as location as so

var txtFile = new File('~/Desktop/Text.txt');//enter path and file name for text file
var saveFolder = new Folder('~/Volumes/9TB-2/Mug Designs saved PSD/')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists


The script finds the first line of text and creates a duplicate file named with the first name in the txt, but doesn't change the content of the text layer or save and close. The new document just stays open in PS.

I also get this error meassage
 Error 1302: No Such element

Line:28

-> var txtLayer =
newFile.Layers.getByName('text');

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

The "~" in the path points to your personal folders. If you're using an external drive, you don't use that. You need set the exact path. I'm unfamilar with Mac's path naming. There are two ways to describe a path. One uses forward slashes '/' and the other uses back slashes '\'. If you use back slashes, you have to use double one. It's best to use the forward slash.

 

The error in line 28 might be due to how you named the text layer. The name is case sensitive, so they have to match your layer name and the name used in the code.

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

That did it. Removing the tilde in the path and making the name of the text layer all lower case fixed it.

Thanks so much again. I have been putting off implementing this idea for 2 years because the idea of manualy changing the text in thousands of files was too daunting. I will still have to go in and adjust the font size for words or phrases with more than 10 characters, but that's only about 5% and I can deal with that.

At some point I can try to figure out how to set the font size in the script and break the source files down and separate them by character totals, but that's for another day.

In the mean time I can get started.

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 ,
Sep 16, 2019 Sep 16, 2019

Copy link to clipboard

Copied

Great. That's how I got into scripting: too lazy to do all that manual formatting.

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
New Here ,
Mar 02, 2023 Mar 02, 2023

Copy link to clipboard

Copied

Hi Chuck,

I know this is an old post, but I used your code and it works really well for my project. My only issue is that the text string (that gets used for the new file name) is too long in my application and and error occurs when photoshop trys to save an invalid name. If I shorten the text it works well. I did try to change line 30 from "textiInfo [i]" to a static string "processed" and it works, but I intend to put multiple new images in the same folder, so I need them to be different. Ideally, the new name would be a truncated version of the text string. Say 6 or 7 characters. I am a newbie at js, but know PS well. Any help would be appreciated. I've attached the script (without my "processed" hack) but with tiff output instead of jpg. 

Thanks,

Mike

 

 

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('/Users/fivek/Desktop/test js code/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder ('/Users/fivek/Desktop/Processed-tifs')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
var txtInfo = readTextFile (txtFile).split('\n');
}
else{
run = false;
alert('There is no text file.')
}

if(run){
for(var i=0;i<txtInfo.length;i++){
dupeFile (txtInfo[i])
var newFile = app.activeDocument;
var txtLayer = newFile.layers.getByName('text');
txtLayer.textItem.contents = txtInfo[i];
newFile.saveAs (new File(saveFolder +'/' + txtInfo[i] + '.tif'), TiffSaveOptions);
newFile.close(SaveOptions.DONOTSAVECHANGES);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//end for loop
}//end if to run

function readTextFile(file){
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str
}
 
function dupeFile(name){
var idDplc = charIDToTypeID( "Dplc" );
var desc5 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idDcmn = charIDToTypeID( "Dcmn" );
var idOrdn = charIDToTypeID( "Ordn" );
var idFrst = charIDToTypeID( "Frst" );
ref1.putEnumerated( idDcmn, idOrdn, idFrst );
desc5.putReference( idnull, ref1 );
var idNm = charIDToTypeID( "Nm " );
desc5.putString( idNm, name );//new name of file .
executeAction( idDplc, desc5, 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
Community Expert ,
Mar 03, 2023 Mar 03, 2023

Copy link to clipboard

Copied

@P-element 

 

I'm not in front of a computer for testing for a couple of days, this is really painful on a phone! You can try the following regular expression for the first 8 characters from the left :

 

txtLayer.textItem.contents = txtInfo[i].replace(/(^.{8})(.*)/, "$1");

 

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
New Here ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

Thanks Stephen!

It actually truncated my text on the new doc and still errored with the ps save, but I stuck the replace after the name on line 29 and it worked well. Thank you.

This script runs along in a photoshop action with other scripts and conditionals in the ps steps, and I just realized that there will be different sizes of images that will use the same text saving to the same directory essentially overwriting files that use the same text string for their names. Is there an easy way to add something in the code so that the file saves an increment version of the file instead of overwriting it?

Latest version attached.

Thank you. I’m sorry you had to type that on a phone!

Mike

#target photoshop

app.preferences.rulerUnits = Units.PIXELS;

var txtFile = new File('/Users/fivek/Desktop/test js code/textFile.txt');//enter path and file name for text file
var saveFolder = new Folder ('/Users/fivek/Desktop/Processed-tifs')
if(!saveFolder.exists){saveFolder.create()};//creates the save folder if it doesn't exists

var psdOptions = new PhotoshopSaveOptions()
psdOptions.layers = true

var doc = activeDocument;//original file

var run = true;

if (txtFile.exists){
var txtInfo = readTextFile (txtFile).split('\n');
}
else{
run = false;
alert('There is no text file.')
}

if(run){
for(var i=0;i dupeFile (txtInfo[i])
var newFile = app.activeDocument;
var txtLayer = newFile.layers.getByName('text');
txtLayer.textItem.contents = txtInfo[i];
newFile.saveAs (new File(saveFolder +'/' + txtInfo[i].replace(/(^.{8})(.*)/, "$1") + '.tif'), TiffSaveOptions); // This is new PS saved name.
newFile.close(SaveOptions.DONOTSAVECHANGES);
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//end for loop
}//end if to run

function readTextFile(file){
file.encoding = "UTF8";
file.lineFeed = "unix";
file.open("r", "TEXT", "????");
var str = file.read();
file.close();
return str
}

function dupeFile(name){
var idDplc = charIDToTypeID( "Dplc" );
var desc5 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idDcmn = charIDToTypeID( "Dcmn" );
var idOrdn = charIDToTypeID( "Ordn" );
var idFrst = charIDToTypeID( "Frst" );
ref1.putEnumerated( idDcmn, idOrdn, idFrst );
desc5.putReference( idnull, ref1 );
var idNm = charIDToTypeID( "Nm " );
desc5.putString( idNm, name );//new name of file .
executeAction( idDplc, desc5, 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
New Here ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

Also, it would be better to have the last part of the text sting copied for the file name instead of the first. Tried to figure that out myself, but it didn't seem readily available. I did easily figure out how to increase the characters though.

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 ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

Please provide an example filename pattern based on the layered file as previously provided. Much better to be clear and precise.

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 ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

quote

Also, it would be better to have the last part of the text sting copied for the file name instead of the first. Tried to figure that out myself, but it didn't seem readily available. I did easily figure out how to increase the characters though.


By @P-element

 

To work from the back/right of the text string in a regular expression, use the $ metacharacter rather than ^:

 

.replace(/(.*)(.{8}$)/, "$2")

 

Regular expressions are all about text patterns, so something simple as the last 8 characters as shown above may not be that flexible. If the code lengths are variable, then knowing the filename pattern would help to offer a more flexible, robust regex.

 

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 ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

Incremental numbers or date/time are of course workable, however, if there are different size versions then adding the pixel dimensions to the end of the filename would probably be best.

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
New Here ,
Mar 04, 2023 Mar 04, 2023

Copy link to clipboard

Copied

The photoshop action sets the file size borders, orientation, resolution, and placeholder text block before this script gets it. The output size are mainly 8x10, 11x14, 16x20, 22x28 and 30x40. All at 300ppi. Not sure if this pre-sized file will prevent the save from reading pixel dimension. The large amount of text that is being placed in the new document (and in the new file name), is most identifiable using the LAST 13 or more characters as it includes the ID number of the image. Ideally, the output file name would read something like  RS71044_11x14.tiff" or RS71044_3300x4200.tif,  but just having incremental numbers or date/time stamp so file aren't overwritten could work too.  Thanks.

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