Skip to main content
kenepic
Inspiring
May 24, 2019
Answered

Quick Export as PNG as standalone script

  • May 24, 2019
  • 5 replies
  • 17479 views

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

This topic has been closed for replies.
Correct answer kenepic

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 );

};


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.

5 replies

Stephen Marsh
Community Expert
Community Expert
February 25, 2022

A couple more options here (works on all root/top-level layers and layer sets):

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/how-do-i-export-layers-as-png-without-loosing-the-size-and-placement-of-the-particular-layer/m-p/12734226

 

All top level layers saved to PNG.jsx
All top level layers exported to PNG.jsx

 

One can record the scripts into an action, then use the Automate > Batch command.

rywalker
Known Participant
June 11, 2019

I was able to find a different method for exporting the files I needed - but if anyone figures out the conditions for executing "AdobeScriptAutomation Scripts" I'm very curious as to when that can and can be used inside a script. At this point it's more a matter of curiosity.

rywalker
Known Participant
June 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.

rywalker
Known Participant
June 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)

kenepic
kenepicAuthor
Inspiring
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).

rywalker
Known Participant
June 5, 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!


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?