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

Quick Export as PNG as standalone script

Explorer ,
May 24, 2019 May 24, 2019

Hello,

TL;DR

I'm looking for a script that exports groups as individual PNGs (with the group name) into a folder with the document name. This is exactly what the "Quick Export as PNG" menu item is suppose to do, but cannot be properly batched.

I've been spinning my wheels on this all morning. Photoshop CC has a really useful feature under the Layers menu (or when Right-Clicking selected groups) called "Quick Export as PNG". It exports the groups as individual images into a folder adjacent to the current document - provided you have that export preference set (eg. file1 images get saved to file1-assets folder). However, it has two major flaws.

  1. When recording the function as an action, the export folder is hardcoded (even if export preferences are set to "export files to an assets folder next to the current document")
  2. It runs asynchronously, so that if you try to run this script as a batch (eg. on file1 file2 file3), it does not actually save any files until after every images has been processed. So there is no way to "grab" the image as they are processed. If the action contains a "close" step, the script fails altogether (nothing exports).

The Quora post "Is it possible to use "Quick Export as PNG" in a Photoshop action?" gives a very good rundown as well if you are looking for a different/better explanation.

And some information in this post as well: How do I quickly export a layer as a png file in Photoshop with extendscript

TOPICS
Actions and scripting
17.2K
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

Explorer , May 28, 2019 May 28, 2019

The Generate > Image Assets is actually an excellent solution for automating export, provided you can find quick/easy ways to name your layers and groups accordingly! (See below)

Heh, wow, Stephan, I can't for the life of me figure out why, but if I remove the comments at the top of your script it works fine... So, your solution effectively works!

The complete solution is as follows.

In a file with multiple groups (layersets) that you wish to export as PNG.

1. First, run this script (to append .png

...
Translate
Adobe
Community Expert ,
May 24, 2019 May 24, 2019
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
Explorer ,
May 24, 2019 May 24, 2019

Hi Stephen,

Thanks for these, but I've been Googling all morning - so I've actually visited all of those! Several of these don't work, and none of them specify a folder based on the documents name (at least that I could figure out). The second to last link was almost a good starting point, but it ran really slow compared to "Quick Export as PNG". Literally over 100x's slower (I have a lot of groups).

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 ,
May 24, 2019 May 24, 2019

Even if slower, this is better than manual, right?

We can't record Quick Export into an action and I can't get the AM code to run from ScriptListener. When you look at what the script is doing it is a time consuming process.

Perhaps Generator could help with the speed issue? File > Generate > Image Assets (ticked)

Then rename your layer groups as required with a .png extension on the end of the group name and you should end up with a new folder of PNG assets in the same path as the original file.

If you had a script that could automatically select all top level layer sets/groups, then you could use a script to add the .png extension as a suffix to all selected sets.

renamer.png

https://raw.githubusercontent.com/Paul-Riggott/PS-Scripts/master/Layer%20Name%20Edit.jsx

Or perhaps look at these layer/set saving scripts if your previous search did not lead you to them:

https://raw.githubusercontent.com/Paul-Riggott/PS-Scripts/master/Layer%20Saver.jsx

or

https://raw.githubusercontent.com/Paul-Riggott/PS-Scripts/master/Layer%20Saver%20Plus.jsx

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 ,
May 24, 2019 May 24, 2019

OK, the following script hack will add .png to all layer set names, which will automatically create PNG image assets via Generator.

// https://forums.adobe.com/message/8519528

// https://forums.adobe.com/message/11092165#11092165

// Script hacked to add .png extension to all layer sets for use with Generator to auto create assets

// Does not work with nested sets/groups inside of sets/groups

  

#target photoshop;

setLayerSetNames();

function setLayerSetNames(){

  var ref = new ActionReference();

  ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "NmbL" ));

  ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );

  var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1;

try{

    activeDocument.backgroundLayer;

var i = 0; }catch(e){ var i = 1; };

  for(i;i<count;i++){

      if(i == 0) continue;

        ref = new ActionReference();

        ref.putIndex( charIDToTypeID( 'Lyr ' ), i );

        var desc = executeActionGet(ref);

        var layerName = desc.getString(charIDToTypeID( 'Nm  ' ));

        var ID = desc.getInteger(stringIDToTypeID( 'layerID' ));

        if(layerName.match(/^<\/Layer group/) ) continue;

        var layerType = typeIDToStringID(desc.getEnumerationValue( stringIDToTypeID( 'layerSection' )));

        var isLayerSet =( layerType == 'layerSectionContent') ? false:true;

if(isLayerSet) setLayerName(ID,layerName.replace(/$/, '\.png'));

  };

};

function setLayerName(ID,Name) {

var desc4 = new ActionDescriptor();

var ref3 = new ActionReference();

ref3.putIdentifier(charIDToTypeID('Lyr '), ID);

desc4.putReference( charIDToTypeID('null'), ref3 );

var desc5 = new ActionDescriptor();

desc5.putString( charIDToTypeID('Nm  '), Name);

desc4.putObject( charIDToTypeID('T  '), charIDToTypeID('Lyr '), desc5 );

executeAction(charIDToTypeID('slct'), desc4, DialogModes.NO);

executeAction( charIDToTypeID('setd'), desc4, DialogModes.NO );

};

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
Explorer ,
May 24, 2019 May 24, 2019

Thanks again Stephen! I wasn't familiar with file->generate. I'm away from the computer, but I'll give this a try asap and report back! 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
Explorer ,
May 28, 2019 May 28, 2019

Hi Stephan,

Sorry for the delay, I was scrambling to fix another issue. I tried the script you wrote, but get an error

Error 1220:Illegal Arguement

Line: 36

-> desc4.putObject( charIDToTypeID('T  '), charIDToTypeID('Lyr '), desc5 );  

I'm digging into it now to see if I can figure it 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 Expert ,
May 28, 2019 May 28, 2019

It worked fine for me in CS6 and CC2018...

All I did was edit one line of code in the original file, that was line 26!

However, the script is a moot point if you don't like the results of the automagical Generator/Image Assets! Did you test by manually adding .png onto the layer set name, or by using the layer renamer script that I posted earlier?

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
Explorer ,
May 28, 2019 May 28, 2019

The rename script (that's the one that threw the error). I'm running CC 2019 fwiw.

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 ,
May 28, 2019 May 28, 2019

Sorry, post #3 or #4?

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
Explorer ,
May 28, 2019 May 28, 2019

Post #4, but I'm going to try manually adding .png right now to see how the "automagical Generator" process works (I'm hopeful).

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
Explorer ,
May 28, 2019 May 28, 2019

Ok. Did a quick test. It works perfect, except... it saves the individual layers, not the groups!

In theory I could just flatten all my groups before the save... but then I'm back to needing the script that you wrote (need a script to append .png to all the layers).

I ran your script again, just on the layers. It didn't give an error this time, but it didn't actually do anything either.

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
Explorer ,
May 28, 2019 May 28, 2019

The Generate > Image Assets is actually an excellent solution for automating export, provided you can find quick/easy ways to name your layers and groups accordingly! (See below)

Heh, wow, Stephan, I can't for the life of me figure out why, but if I remove the comments at the top of your script it works fine... So, your solution effectively works!

The complete solution is as follows.

In a file with multiple groups (layersets) that you wish to export as PNG.

1. First, run this script (to append .png to all layers sets) - Credit Stephen_A_Marsh and SuperMerlin (Is it possible to convert layerset names to uppercase? )

#target photoshop; 

setLayerSetNames(); 

function setLayerSetNames(){  

   var ref = new ActionReference();  

   ref.putProperty( charIDToTypeID("Prpr") , charIDToTypeID( "NmbL" )); 

   ref.putEnumerated( charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );  

   var count = executeActionGet(ref).getInteger(charIDToTypeID('NmbL')) +1;  

try{ 

    activeDocument.backgroundLayer; 

var i = 0; }catch(e){ var i = 1; }; 

   for(i;i<count;i++){  

       if(i == 0) continue; 

        ref = new ActionReference();  

        ref.putIndex( charIDToTypeID( 'Lyr ' ), i ); 

        var desc = executeActionGet(ref); 

        var layerName = desc.getString(charIDToTypeID( 'Nm  ' )); 

        var ID = desc.getInteger(stringIDToTypeID( 'layerID' )); 

        if(layerName.match(/^<\/Layer group/) ) continue; 

        var layerType = typeIDToStringID(desc.getEnumerationValue( stringIDToTypeID( 'layerSection' ))); 

        var isLayerSet =( layerType == 'layerSectionContent') ? false:true; 

if(isLayerSet) setLayerName(ID,layerName.replace(/$/, '\.png')); 

   };  

}; 

function setLayerName(ID,Name) { 

var desc4 = new ActionDescriptor(); 

var ref3 = new ActionReference(); 

ref3.putIdentifier(charIDToTypeID('Lyr '), ID); 

desc4.putReference( charIDToTypeID('null'), ref3 ); 

var desc5 = new ActionDescriptor(); 

desc5.putString( charIDToTypeID('Nm  '), Name); 

desc4.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), desc5 ); 

executeAction(charIDToTypeID('slct'), desc4, DialogModes.NO); 

executeAction( charIDToTypeID('setd'), desc4, DialogModes.NO ); 

};

Which renames the groups with a .png extension.

2. Make sure Generate Assets > Image Assets is checked. If you want to do this via an action, there are two ways:

  1. Insert the menu item into an action
  2. var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" ); 

        var desc885 = new ActionDescriptor(); 

        var idjsNm = charIDToTypeID( "jsNm" ); 

        desc885.putString( idjsNm, """Image Assets""" ); 

    executeAction( idAdobeScriptAutomationScripts, desc885, DialogModes.NO ); 

3. Now save. This will save the document as well as an adjacent folder called [documentname]-assets which will include a PNG for every layer and/or group with the .png extension

  • note - in my case all layers also had a .png extension, which was it's own, separate hassle
  • note2 - this may be in some ways connected to your export settings. If you are not getting a separate folder, try checking those settings

All of this can be recorded as actions, and therefore completely automate-able.

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
Explorer ,
May 28, 2019 May 28, 2019

Ugh, Stephan. There's a critical flaw in this method 😞 😞

File > Generate > Image Assets is not a global setting. It's set per file. And you cannot toggle it on via an action. So it does not work for batch automating. So close. Very frustrating. Let me know if you can think of a way around this.

From the original Generator github

Generate Image Assets Functional Spec · adobe-photoshop/generator-assets Wiki · GitHub

The generation of image assets is enabled on a per document basis and is off by default. However, once the user selects Generate -> Image Assets, the plug-in will remember that choice until the user disables image assets ( by selecting Generate -> Image Assets again ) for that document or disables Generator completely, via the preferences dialog.

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 ,
May 28, 2019 May 28, 2019

I tested the following two methods on a new file that had never had Generator used and both methods worked in enabling image assets to be ticked/active:

1) insert the menu item into an action

2) ScriptListener recorded AM code:

var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" );

    var desc885 = new ActionDescriptor();

    var idjsNm = charIDToTypeID( "jsNm" );

    desc885.putString( idjsNm, """Image Assets""" );

executeAction( idAdobeScriptAutomationScripts, desc885, DialogModes.NO );

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
Explorer ,
May 28, 2019 May 28, 2019

Brilliant! Works for me as well. I always forget about menu item. I guess mostly because it rarely works for the things I want it to!

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 ,
Jun 05, 2019 Jun 05, 2019

Is there a way to customize where generated files save to? or can they only save into a file adjacent to the original file?

**Edit

I reviewed this functionality a bit more - it looks like these assets can be put into named subfolders by renaming layers to "[subfolder name]/[asset/layer name].[asset type]"

One problem I've run into with trying to script using this functionality is that I need to toggle on Generate > Image Assets so that renaming the layers generates the assets. The Action manager code shown earlier allows you to add the menu item to an action, but I'm not sure how to toggle this feature on or off - or even how to check if it is toggled on within a script (I don't want to turn it off it is already on.)

Any ideas as to how I could go about doing this to those of you who have worked using this functionality?

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 ,
Jun 05, 2019 Jun 05, 2019

Some background info:

Introducing Adobe Generator for Photoshop CC | Photoshop Blog by Adobe

Create image assets from layers in Photoshop  (anchored link to modifying settings)

However, outside of the basics, you would need to edit the underlying generator code for the base-directory. There are lots of threads and hints over at the feedback site, examples here:

Photoshop: How do I customize the export folder name in Generator? | Photoshop Family Customer Commu...

Photoshop Generator: Create Folders in Image Assets | Photoshop Family Customer Community

However, the best that I was able to dig up in a quick search was the following (there are many repos on GitHub regarding generator, there may be others that are better or easier to implement):

Configuration Options · adobe-photoshop/generator-assets Wiki · GitHub

Good luck!

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
Explorer ,
Jun 07, 2019 Jun 07, 2019

I had that same question/problem. Luckily you can simply insert "Generate>Image Assets as a menu item into the action ("Insert Menu Item..." in the action panel)

Or you can insert this AM code/script (from Script Listener)

var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" );   

    var desc885 = new ActionDescriptor();   

    var idjsNm = charIDToTypeID( "jsNm" );   

    desc885.putString( idjsNm, """Image Assets""" );   

executeAction( idAdobeScriptAutomationScripts, desc885, DialogModes.NO );

Personally I chose to run the script as the script only turns it on, not off. i.e. it's not a toggle (toggle on/off), it's effectively a "set on" script. So if it's "on" it will stay "on" if you run the script again.

Worth noting, the generate image assets state is saved with the file.

From the original Generator github

Generate Image Assets Functional Spec · adobe-photoshop/generator-assets Wiki · GitHub

The generation of image assets is enabled on a per document basis and is off by default. However, once the user selects Generate -> Image Assets, the plug-in will remember that choice until the user disables image assets ( by selecting Generate -> Image Assets again ) for that document or disables Generator completely, via the preferences dialog.

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 ,
Jun 10, 2019 Jun 10, 2019

The above works....some of the time

When I was testing out my primary function (unlocking the layer, turning on generator, then renaming the layer) it worked fine.

But when I try to insert this function into a loop, I get an 8800 error

- The command “Scripts” is not currently available.

Line: 297

->  executeAction( sTID( "AdobeScriptAutomation Scripts" ), jsDesc, DialogModes.NO );

The basics of my script is this - it currently gets stuck on the turnOnGenerator() which is the Action Manager code you posted above.

    var comps = File.openDialog("Select Avatar Comps", undefined, true);

    for (var i = 0; i < comps.length; i++){

         var f = comps;

         openFile(f);

         unlockBG();

         turnOnGenerator();

         var name = f.name.substring( 0, f.name.indexOf('.') ).toUpperCase();

         var folder = Folder( f.path+"/"+name );

         if ( !folder.exists ){ folder.create() };

         exportAvatars( folder.fullName, 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
Explorer ,
Jun 10, 2019 Jun 10, 2019

I ran into that once myself, but I believe only when I incorrectly tweaked the script. I can't remember the specifics unfortunately.

However, I've run that script as part of a complex action over hundreds of images since this post without problem. I'm running the action as an automated batch.

What do you mean by "loop" exactly? That could be part of the problem. You could also try installing the Script Listener plugin (if you haven't already) and see if your script (when you turn on generate image assets) is somehow different.

Sorry I can't offer better suggestions. Hopefully one of these guys/girls who are more competent with scripting can chime in.

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 ,
Jun 10, 2019 Jun 10, 2019

For what its worth, here is the AM code from my post #14 converted through Clean SL:

AdobeScriptAutomationScripts();

function AdobeScriptAutomationScripts() {

  var s2t = function (s) {

  return app.stringIDToTypeID(s);

  };

  var descriptor = new ActionDescriptor();

  descriptor.putString( s2t( "javaScriptName" ), "Image Assets" );

  executeAction( s2t( "AdobeScriptAutomation Scripts" ), descriptor, DialogModes.NO );

}

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 24, 2022 Feb 24, 2022

Another method to turn on Generate Image Assets via scripting:

 

$.evalFile(File(app.path + '/Presets/Scripts/generate.jsx'));
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 ,
Jun 10, 2019 Jun 10, 2019

After a bit more testing, it looks like this bit of AM code can't run after opening a file during a script. Maybe that might help determine the cause as to why it's resulting in the 8800 error. (if anyone knows why this is happening or how I can fix it - it would be greatly appreciated)

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 ,
Jun 11, 2019 Jun 11, 2019

This is pretty much the exact same function I have for my "turnOnGenerator" function.

But from what I understand there's something preventing "AdobeScriptAutomation Scripts" from executing when you try to run this function after opening a file within a script.

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