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

How to use text layer content inside a smart layer to name the export file

Community Beginner ,
Jan 30, 2024 Jan 30, 2024

Hi fellow Photoshop users.

I start by saying that I'm quite a newbie about PS scripting, even if I'm a professional designer and PS user since 1999.

 

The subject says almost all.

 

This is the situation:

- I have PSD with 4 artboards;

- all artboards have a the same smart layer containing only one text level with a number (let's say it's "01");

- the same smart layer is also floating outside all artboards so I can just easily find it everytime I need to update the number on alla layers at once;

 

Every day I need to

- export all artboards in PNG

- export one specific artboard (let's call it "landscape") in JPG and rename all of them using some constant text + the number contained into the smart layer mentioned above + the name of the arboard

 

i.e.

MyConstantText-01-portrait.png

MyConstantText-01-landscape.png

MyConstantText-01-banner.png

MyConstantText-01-landscape.jpg

 

As I need to do this several times a day every week from different PSD source file I was asking myself if there's any way to do this with an action or scripting function that I can use on whatever source file.

 

I've seen different posts on this board about naming a file using a text layer but this seems to be a bit more complicated and I could'nt figure out how to put all the things I learnt here togegher to make the script I need.

 

Thanks in advance to anyone who can help.

 

Alessandro

TOPICS
Actions and scripting
729
Translate
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

correct answers 1 Correct answer

Community Expert , Jan 30, 2024 Jan 30, 2024

Screenshot 2024-01-30 at 16.19.40.pngScreenshot 2024-01-30 at 16.20.02.png

 

 

 

// save png for each artboard and jpg for "Artboard 1";
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = app.activeDocument;
var docName = myDocument.name;
try {
var basename = docName.match(/(.*)\.[^\.]+$/)[1];
var origDocPath = myDocument.fullName;
var docPath = myDocument.path;
}
catch (e) {
var basename = myDocument.name;
var docPath = "~/Desktop"
};
//////
...
Translate
Adobe
Community Expert ,
Jan 30, 2024 Jan 30, 2024

That’s 3 pngs and one jpg, but you stated 4 Artboards. 

I think it would be best to provide the sample file or at the very least meaningful screenshots (including all pertinent Panels) to illustrate the whole Layer and File structure. 

Translate
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 30, 2024 Jan 30, 2024

Good point. I'll try to be more specific and if it doesn't sound comprehensive, I'll follow your advise.

 

There's artboards A, B, C, D.

I need to export all of them as PNGs AND one of them, let's say artboard A, as a JPG.

 

I hope it's more clear 🙂 

 

And thanks for your answer.

Translate
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 ,
Jan 30, 2024 Jan 30, 2024

If a picture is worth a thousand words, please post a screenshot of the layers panel and preferably a sample file so that those freely offering their time are not spending extra time creating test assets.

 

Or put another way, help others to help you.

Translate
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 ,
Jan 30, 2024 Jan 30, 2024

Screenshot 2024-01-30 at 16.19.40.pngScreenshot 2024-01-30 at 16.20.02.png

 

 

 

// save png for each artboard and jpg for "Artboard 1";
// 2024, use it at your own risk;
if (app.documents.length > 0) {
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = app.activeDocument;
var docName = myDocument.name;
try {
var basename = docName.match(/(.*)\.[^\.]+$/)[1];
var origDocPath = myDocument.fullName;
var docPath = myDocument.path;
}
catch (e) {
var basename = myDocument.name;
var docPath = "~/Desktop"
};
////////////////////////////////////
var theSO = openSmartObject(myDocument.layers.getByName("NUM"));
if (theSO == false) {alert ("please select the smart object")} else {
var theTypeLayers = collectTypeLayers ();
theSO.close(SaveOptions.DONOTSAVECHANGES);
if (theTypeLayers.length == 1) {
////////////////////////////////////
var theLayerSets = collectArtBoards ();
for (var m = 0; m < theLayerSets.length; m++) {
    var theCopy = myDocument.duplicate("copy", true);
    cropImageTo (theLayerSets[m][3]);
    savePNG (myDocument, docPath, basename, theLayerSets[m][0]+"_"+theTypeLayers[0][3]);
    if (theLayerSets[m][0] == "landscape <- PNG & JPG (Web, 1280x720, compr 90)") {
        theCopy.bitsPerChannel = BitsPerChannelType.EIGHT;
        saveJPG (activeDocument, docPath, basename, theLayerSets[m][0]+"_"+theTypeLayers[0][3])
    };
    theCopy.close(SaveOptions.DONOTSAVECHANGES)
};
} else {alert ("more than one type layer in the smart object")};
};
app.preferences.rulerUnits = originalRulerUnits;
};
////// collect artboards //////
function collectArtBoards () {
// get number of layers;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var artboardEn = layerDesc.getBoolean(stringIDToTypeID("artboardEnabled"));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
if (layerSet != "layerSectionEnd" && layerSet == "layerSectionStart" && isBackground != true && artboardEn == true) {    
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
//var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theArtboard = layerDesc.getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
//checkDesc2(theArtboard, true);
var theseBounds = [theArtboard.getUnitDoubleValue(stringIDToTypeID("left")), theArtboard.getUnitDoubleValue(stringIDToTypeID("top")), theArtboard.getUnitDoubleValue(stringIDToTypeID("right")), theArtboard.getUnitDoubleValue(stringIDToTypeID("bottom"))];
theLayers.push([theName, theIndex, theID, theseBounds])
};
}
catch (e) {};
};
return theLayers
};
////// function to png //////
function savePNG (myDocument, docPath, basename, theSuffix) {
var desc10 = new ActionDescriptor();
var desc11 = new ActionDescriptor();
desc11.putEnumerated( stringIDToTypeID( "method" ), stringIDToTypeID( "PNGMethod" ), stringIDToTypeID( "quick" ) );
desc11.putEnumerated( stringIDToTypeID( "PNGInterlaceType" ), stringIDToTypeID( "PNGInterlaceType" ), stringIDToTypeID( "PNGInterlaceNone" ) );
desc11.putEnumerated( stringIDToTypeID( "PNGFilter" ), stringIDToTypeID( "PNGFilter" ), stringIDToTypeID( "PNGFilterAdaptive" ) );
desc11.putInteger( stringIDToTypeID( "compression" ), 6 );
desc11.putEnumerated( stringIDToTypeID( "embedIccProfileLastState" ), stringIDToTypeID( "embedOff" ), stringIDToTypeID( "embedOff" ) );
var idPNGFormat = stringIDToTypeID( "PNGFormat" );
desc10.putObject( stringIDToTypeID( "as" ), idPNGFormat, desc11 );
desc10.putPath( stringIDToTypeID( "in" ), new File( docPath+"/"+basename+"_"+theSuffix+".png" ) );
desc10.putBoolean( stringIDToTypeID( "copy" ), true );
desc10.putBoolean( stringIDToTypeID( "lowerCase" ), true );
desc10.putBoolean( stringIDToTypeID( "embedProfiles" ), true );
desc10.putEnumerated( stringIDToTypeID( "saveStage" ), stringIDToTypeID( "saveStageType" ), stringIDToTypeID( "saveSucceeded" ) );
executeAction( stringIDToTypeID( "save" ), desc10, DialogModes.NO );
};
////// function to jpg //////
function saveJPG (myDocument, docPath, basename, theSuffix) {
myDocument = myDocument.duplicate("copy", true);
myDocument.flatten();
var jpgopts = new JPEGSaveOptions();
jpgopts.embedProfile = true;
jpgopts.formatOptions = FormatOptions.STANDARDBASELINE;
jpgopts.matte = MatteType.NONE;
jpgopts.quality = 12;
myDocument.saveAs((new File(docPath+"/"+basename+"_"+theSuffix+".jpg")),jpgopts,false);
myDocument.close()
};
////// crop //////
function cropImageTo (theBounds) {
var desc7 = new ActionDescriptor();
var desc8 = new ActionDescriptor();
var idPxl = charIDToTypeID( "#Pxl" );
desc8.putUnitDouble( charIDToTypeID( "Top " ), idPxl, theBounds[1] );
desc8.putUnitDouble( charIDToTypeID( "Left" ), idPxl, theBounds[0] );
desc8.putUnitDouble( charIDToTypeID( "Btom" ), idPxl, theBounds[3] );
desc8.putUnitDouble( charIDToTypeID( "Rght" ), idPxl, theBounds[2] );
var idRctn = charIDToTypeID( "Rctn" );
desc7.putObject( charIDToTypeID( "T   " ), idRctn, desc8 );
desc7.putUnitDouble( charIDToTypeID( "Angl" ), charIDToTypeID( "#Ang" ), 0.000000 );
desc7.putBoolean( charIDToTypeID( "Dlt " ), false );
desc7.putEnumerated( stringIDToTypeID( "cropAspectRatioModeKey" ), stringIDToTypeID( "cropAspectRatioModeClass" ), stringIDToTypeID( "pureAspectRatio" ) );
desc7.putBoolean( charIDToTypeID( "CnsP" ), false );
executeAction( charIDToTypeID( "Crop" ), desc7, DialogModes.NO );
};
////// open smart object //////
function openSmartObject (theLayer) {
try {
activeDocument.activeLayer = theLayer;
// =======================================================
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
    var desc2 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc2, DialogModes.NO );
return app.activeDocument
} catch (e) {return false}
};
////// collect type layers //////
function collectTypeLayers () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true && layerDesc.hasKey(stringIDToTypeID("textKey")) == true) {
var visible = layerDesc.getBoolean(stringIDToTypeID("visible"));
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var theText = textDesc.getString(stringIDToTypeID('textKey'));
theLayers.push([theName, theID, visible, theText])
};
}
catch (e) {};
};
return theLayers
};

 

 

edited again 2024-02-28

 

Translate
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 ,
Feb 27, 2024 Feb 27, 2024

My dear @c.pfaffenbichler

 

Finally I had the chance to analyze and test your script. 
I'm quite sure I need to study a little more to understand everything, but I got the most of it. 😉

 

Unfortunately there something going wrong. 

Cycle looks good for PNGs but when it gets to export the JPG I get a "Save As" dialog asking me to manually save a file with the correct JPG filename BUT with PSD extension.

 

IF: I do click "save" as asked, it saves the file as PSD and closes the JPG "copy" file but asks me is I wanna save it or not, then it closes the PNG copy file and the cycle ends with no errors. But with a PSD instead of a JPG.

ELSE IF: I discard the save request, the two "copy" files created by the script stay opened and I get this error message at Line 107

 

myDocument.saveAs((new File(docPath+"/"+basename+"_"+theSuffix+".jpg")),jpgopts,false);

 

 

I can't figure out how to solve this, so I'm asking you for help.

 

Beside this, I only have a couple of request to add (I forgot to specify them at the beginning):

1. is it possible to export the JPG "for web" with a specified resizing (maintaining proportions) and compression? I need it to be under 2 MB.

2. can we just set in the script the Smart Object layer name for the text to use, instead of having to manually select it before running the script? 

 

Thanks for all you've done.

Cheers

 

Alessandro

Translate
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 ,
Feb 27, 2024 Feb 27, 2024

Can you please provide the psd-file (feel free to remove any sensitive content) for testing? 

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

Here's a clean version of the PSD file: https://we.tl/t-Dg61n8NKqa

I will use this script on other files too with more artboards, but all of them are similar very to this (I will adapt the other files structure to the script).

 

Thanks for your help. 

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

I edited the code, please try that. 

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

Tried the new code (with the same file I sent you), but I got the PNGs and no JPG in my folder.

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

Could it be you renamed the Artboard? 

Because here it seems to work fine. 

Screenshot 2024-02-28 at 11.57.21.pngScreenshot 2024-02-28 at 11.58.12.png

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

Sorry my friend, I must have done that, but not in purpose. 

Now it works just fine 🙂 

 

Many thanks for your help.

Cheers

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

You can change the name for the jpg-Artboard in the line: 

if (theLayerSets[m][0] == "landscape <- PNG & JPG (Web, 1280x720, compr 90)") {

 You could also change the clause not to check for an exact name but to »look for« some element in the name. 

Translate
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 ,
Feb 28, 2024 Feb 28, 2024
LATEST

Thanks for the explanation mate. I will take some time during the weekend and go through the whole code to fully understand it, even If I've seen you already commented it which is really helpful.

Translate
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 ,
Jan 31, 2024 Jan 31, 2024

@pandinsky 

 

How does the script from @c.pfaffenbichler work for you?

 

Translate
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 ,
Jan 31, 2024 Jan 31, 2024

Maybe I should have explained for the OP’s sake that the line 

    if (theLayerSets[m][0] == "Artboard 1") {saveJPG (activeDocument, docPath, basename, theLayerSets[m][0]+"_"+theTypeLayers[0][3])};

determines whether a jpg will be produced for an Artboard – in this case if its name is exactly »Artboard 1«. 

So changing that part to the intended name should work out. 

Translate
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 31, 2024 Jan 31, 2024

Sorry guys. Been quite busy 🙂 

 

I'll try @c.pfaffenbichler solution ASAP. Thanks, btw!

But it really looks like you got the point.

Translate
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 ,
Feb 28, 2024 Feb 28, 2024

To use text layer content inside a smart layer to name the export file in Adobe Photoshop, you can follow these steps:

1. **Set Up Your Document**: Open your Photoshop document (.PSD) containing the text layer and smart object you want to use for naming the export file.

2. **Create a Text Layer**: If you haven't already, create a text layer with the desired content that you want to use for naming the export file. This text layer should be inside the smart object you're using.

3. **Convert Text Layer to Smart Object (Optional)**: If the text layer is not already part of the smart object, you can convert it into one. Right-click on the text layer and choose "Convert to Smart Object" from the context menu.

4. **Edit Smart Object Contents**: Double-click on the smart object's thumbnail in the Layers panel to open its contents. This will open a new tab with the contents of the smart object.

5. **Link Layer Names to Text Layer**: Inside the smart object's contents, create a new layer and use the Text tool to create a text box. Right-click on the text layer and choose "Convert to Smart Object" from the context menu.

6. **Set up Layer Name**: Double-click on the layer name to make it editable. Then, type in the desired name or use the Type tool to link it to the text layer in the smart object.

7. **Save and Close Smart Object**: Once you've set up the text layer content to name the export file, save the changes to the smart object and close its tab.

8. **Export Your File**: Back in the main document, go to File > Export > Export As or Save for Web (Legacy) to export your file. The export file name will now reflect the content of the linked text layer within the smart object.

By following these steps, you can use text layer content inside a smart layer to name the export file in Adobe Photoshop. This allows for dynamic file naming based on the content of the text layer within the smart object.

Translate
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