Help getting a script started.

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

j_forrester

Help getting a script started.

Post by j_forrester »

Sorry for any confusion and thanks for your patience.

As I render off a lot off CG mask files (RGB images with black elsewhere) I wanted a script to automatically build my photoshop stack with a named layerset with mask.

In my 3D application I attach a render element to an object which in turn renders that element red against a black background. Depending on the angle of the camera it may be visible in one view but not another view. If the render "mk_" file is completely black it means that the object is not seen in that view, therefor it does not need to make a named layerset because it is irrelevant in this view.

Maybe I was over complicating the process before. A simpler process below.

The script could load all files beginning "mk_" from a chosen folder. (a bit like load files into stack but only with "mk_" start to filename)
Once all files are loaded. It isolates each artlayer and checks for any none black pixels in the red channel. If there are it creates a named layerset as described before and applies the layermask to that layerset. "mk_stone.tga" becomes a named layerset "stone set" or "stone_set" not sure if you can leave a space, if not an underscore would be fine?!
If no non-black pixels are selected it doesn't create a named layerset and moves onto the next artlayer until all have been checked and processed.

If there are 30 "mk_" artlayers loaded in total and 18 have non-black pixels then 12 named layersets will be created. (ideally all layersets would have a red colour applied). At the end of the script all artlayers should be deleted from the active file as they are no longer need to exist in this file.

I have attached a layered PSD file showing the final outcome from the script. I have left the artlayers at the bottom of this file just to show how and where the layermasks are applied, these artlayers would ideally be deleted after all have been checked.

I have also attached another badly coded script to give you an idea of what I am trying to achieve, this does work until it finds an artlayer with no non-black pixels in the red channel, I've since realized a lot this script could have been shortened, but was my very first attempt. With this script I also had to manually tell it what artlayer to use as a mask and what to name the empty layerset. Alot of setting up.

If you open the finished PSD file. delete all the layersets once you have understood the structure and then run the atached script it will show you roughly what I am trying to achieve, but with a more automated process.

Mike, thanks again for your help and time.

sample files and BAD coding.zip (70.86 KiB) Downloaded 6 times
Mike Hale

Help getting a script started.

Post by Mike Hale »

If I understand what you are trying to do this should be close. It does use the Adobe script 'Load Files into Stack.jsx' so you may need to edit the include path to match your Photoshop version and OS.
Code: Select allvar loadLayersFromScript = true;// needed for 'Load FIles into Stack.jsx' and needed to be defined before including that file
// you may ned to edit the include path for different versions or OS.
//@includepath "/c/Program Files/Adobe/Adobe Photoshop CS5/Presets/Scripts/"
//@include "Load Files into Stack.jsx"
//@show include

var selectedFolder = Folder.selectDialog( "Please select top level folder");
if(selectedFolder != null ){// make sure user selected a folder and didn't cancel the dialog
   var files = selectedFolder.getFiles('mk_*.tga');// get only the tga files that start with 'mk_' in the selected folder
   if( files.length > 0 ){// make sure that there is at least one file to process
      loadLayers.intoStack( files );// load the found files into a stack
      var stackDoc = app.activeDocument;
      var totalPixels = stackDoc.width.as('px')*stackDoc.height.as('px');// needed to check for all black red channel
      var layersToRemove = new Array();// make an array to hold all black red channels layers to remove after loop.
      for(var l = 0; l<stackDoc.artLayers.length;l++){
         if( stackDoc.channels[0].histogram[0] == totalPixels ) layersToRemove.push( stackDoc.artLayers[l] );
         stackDoc.activeLayer.visible = false;// hide the layer
         selectLayerBelow();
      }
      for( var l =0; l<layersToRemove.length;l++ ){// now remove all the all black red channel layers
         layersToRemove[l].remove();
      }
      
      for(var l = 0; l<stackDoc.artLayers.length;l++){
         var newSet = stackDoc.layerSets.add();
         newSet.name = stackDoc.artLayers[l].name.match(/mk_(.+)\.tga/)[1]+' set';
         createLayerMask();// create a white mask
         applyRedChannelAsMask(stackDoc.artLayers[l]);// apply the red channel to the layer mask
         newSet.move( stackDoc, ElementPlacement.PLACEATBEGINNING );// move to top of stack
      }
   }
}

function selectLayerBelow(){
    var desc = new ActionDescriptor();
        var ref = new ActionReference();
        ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Bckw" ) );
    desc.putReference( charIDToTypeID( "null" ), ref );
    desc.putBoolean( charIDToTypeID( "MkVs" ), false );
   executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );
};
function createLayerMask(){
   var desc = new ActionDescriptor();
   desc.putClass( charIDToTypeID( "Nw  " ), charIDToTypeID( "Chnl" ) );
   var ref = new ActionReference();
      ref.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Msk " ) );
   desc.putReference( charIDToTypeID( "At  " ), ref );
   desc.putEnumerated( charIDToTypeID( "Usng" ), charIDToTypeID( "UsrM" ), charIDToTypeID( "RvlA" ) );
   executeAction( charIDToTypeID( "Mk  " ), desc, DialogModes.NO );
};
function applyRedChannelAsMask( layer ) {
   var desc = new ActionDescriptor();
      var channelDesc = new ActionDescriptor();
      var channelRef = new ActionReference();
      channelRef.putEnumerated( charIDToTypeID('Chnl'), charIDToTypeID('Chnl'), charIDToTypeID('Rd  ') );
      channelRef.putName( charIDToTypeID('Lyr '), layer.name );
      channelDesc.putReference( charIDToTypeID('T   '), channelRef );
      channelDesc.putBoolean( charIDToTypeID('PrsT'), true );
   desc.putObject( charIDToTypeID('With'), charIDToTypeID('Clcl'), channelDesc );
   executeAction( charIDToTypeID('AppI'), desc, DialogModes.NO );
};
j_forrester

Help getting a script started.

Post by j_forrester »

Thanks Mike,

I use both Mac and PC so have edited the include path.

On the Mac I have edited, include path "/Macintosh/Applications/Adobe Photoshop CS3/Presets/Scripts/". This now works.

The script now stops on the next line of code(line 4),but I dont know how to edit this as this is the name of the named script in my Photoshop Scripts folder.
//@include "Load Files into Stack.jsx"



Really look forward to testing it. Thank you
Mike Hale

Help getting a script started.

Post by Mike Hale »

If it is stopping on that line that means it can't find the script file to include. Make sure there is not a space between include and path as you posted. It should be

//@includepath 'pathtoscriptsfolder'

Note also that the // and @ are both needed.
j_forrester

Help getting a script started.

Post by j_forrester »

Mike I have attached a screen grab of the code i have changed and where it is getting stuck (line in orange). The gap in the last post was just me hand writing the text as opposed to copying it. Still no sure whats happening.

screen grab.jpg.zip (194.13 KiB) Downloaded 7 times
Mike Hale

Help getting a script started.

Post by Mike Hale »

It still looks like the script can not find the Adobe script. I don't know what to say if the path is correct.

Maybe one of our Mac users can help.