removing unwanted pixels from a layered PSD

Photoshop Script Snippets - Note: Full Scripts go in the Photoshop Scripts Forum

Moderators: Tom, Kukurykus

Mike Hale

removing unwanted pixels from a layered PSD

Post by Mike Hale »

Someone at the Adobe forum ask for this. I posted it here so that the code wouldn't get scrambled.

Code: Select allmain = function(){
layer2Selection = function(){
if(app.activeDocument.activeLayer.isBackgroundLayer){
   return;
   }
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
desc.putReference( charIDToTypeID( "null" ), ref );
var ref1 = new ActionReference();
ref1.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) );
desc.putReference( charIDToTypeID( "T   " ), ref1 );
executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
}

addLayer2Selection = function(){
if(app.activeDocument.activeLayer.isBackgroundLayer){
   return;
   }
   var desc = new ActionDescriptor();
   var ref = new ActionReference();
   ref.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ) , charIDToTypeID( "Trsp" ) );
   desc.putReference( charIDToTypeID( "null" ), ref );
   var ref1 = new ActionReference();
   ref1.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) );
   desc.putReference( charIDToTypeID( "T   " ), ref1 );
   executeAction( charIDToTypeID( "Add " ), desc, DialogModes.NO );
}
var doc = app.activeDocument;
var layersToClip = doc.artLayers.length - 2;//don't count top and background layers
doc.activeLayer = doc.artLayers[0];//start with top layer
layer2Selection();//make the first selection

for( i = 0; i < layersToClip; i++){
doc.activeLayer = doc.artLayers[i+1];//switch to next layer
doc.selection.clear();//clear the layer of unwanted pixels
addLayer2Selection();//add remaining pixels to the selection
}
doc.selection.deselect();
}
main();
paPus

removing unwanted pixels from a layered PSD

Post by paPus »

I was that one.
Thank you very much, i will try the code in an hour or so!
Thanks!

Edit: I have just tried it, and yes, it works. I will correct some things and post it back here.

Edit2: I don't have time to figure it out yet (i am having 4 weeks of exams at the informatics university) ... The problem with the above script, that i wanted to correct is, that since some layers have got semitransparent pixels, in the Layers palette i still see the layer as big as it was before (even though half of it is almost transparent), and Photoshop still says that the bounds are where the old bound were. What i would like to do (and i will (if nobody else wants to do it from here), after my exams) is to turn the selection into a mask and apply a threshold of 50% to it, and back to selection of course, so that my selection is totally opac (non transparent).

Thank you very much again!
paPus
Mike Hale

removing unwanted pixels from a layered PSD

Post by Mike Hale »

paPus wrote:What i would like to do (and i will (if nobody else wants to do it from here), after my exams) is to turn the selection into a mask and apply a threshold of 50% to it, and back to selection of course, so that my selection is totally opac (non transparent).

That is what you have now. What you descride above with the layer mask would still leave the same amount of trasparent pixels.

If you don't want any transparent pixels left, you would need to apply a threshold of 0 or 1.

Let me know if that is what you are trying to do
paPus

removing unwanted pixels from a layered PSD

Post by paPus »

If you don't want any transparent pixels left, you would need to apply a threshold of 0 or 1.
threshold ( image->Adjustments->Threshold) never leaves transparent pixels! Threshold first turns the selection into BW and any pixel that has a value above the given one will be black, otherwise white (or opac and transparent). But you probably knew this already.
Probably my "50%" was wrong and should have written 128


oh, i think i understand what the problem was:
paPus wrote: turn the selection into a mask - i ment quick mask, not layer mask
Mike Hale

removing unwanted pixels from a layered PSD

Post by Mike Hale »

Maybe I don't understand what you want to do here.

When you ctrl-click on a layer icon you load the layer's transparency mask as a selection. The more a pixel is transparent the less it is selected.

If the layer has pixels with some transparency, when you enter quick mask mode you sould have a greyscale mask. If you apply a threshold of 128 or 50% it does turn into a bitmap image. The pixels are either black or white. But when you exit quick and delete the selection, only the pixels that are more than 50% transparent are deleted. This leaves you with some semi-transparent pixels.

The only way I know to remove all semi-transparent pixels is to load the transparency mask, enter quick mask, apply a threshold of 0 then exit quick mask. Depending on what you are trying to do you may need to invert the selection.

Later today I will edit this script to add the quick mask/threshold steps and set it up so you can set the amount of threshold so you can adjust it to fit your needs.

By the way, why are you doing this? To make the file size smaller?
paPus

removing unwanted pixels from a layered PSD

Post by paPus »

Thank you very much for the interrest and the big help!!!!
I hope i will have the time to pay it back

However, i don't think you understand what i want. Not completely! If you apply the "Threshold" to ANY layer or to a quick mask, it won't leave, just 0 and 255 ... nothing else!! ( ok, if you're working in 3 bytes, not one, than#000000 and #FFFFFF ).
The amount you set refers to what should be completely black and what completely white. Please try it on a color image, for example.
If i'm still not clear, i will send a very short video, to demonstrate what i'm talking about. Sorry, if i'm still not understandable

I need this little script, because i wrote in maxscript a PSD mapper. We're making whole New York, for a game (doesn't mater which) and mapping and building took a lot of time. I wrote a nice littel maxscript for it, and now, even though the others aren't used to the script yet, they build the buildings 3-4 times faster, and mapping is ... dunno ... 10 times faster with script . This PSD mapper works in the following way:
I run a short script for Photshop, that generates a maxscript type array with the layer's bounds, and saves it into a file. This normally doesn't take more than 3-5 seconds. After that i select this file with my maxscript nad it loads a panel with the layers as buttons. If i select a polygon in 3ds max, and click on a layer on my panel, it applyes the coordinates of the selected layer to that particalar n sided polygon.
Now the problem is, that some layers overlap, therefore Photoshop gives me the wrong starting coordinates (actually it's the right one, but not what i see), therfore the wrong button is generated and the wrong coordinates are given to the poly.

I hope this sums it up
Thanks for reading and helping
Mike Hale

removing unwanted pixels from a layered PSD

Post by Mike Hale »

I think that we are talking about two different things. I was talking doing the threshold while in quick mask to change the selection from a soft edge, featherd selection to a hard edge one. But let's set that aside.

Can you email me a sample PSD so I can see exactly what you are working with?

If you can't send a file, please describe it fully. Do the layers have layer or vector mask? Do they have semi-transparent pixels?
Mike Hale

removing unwanted pixels from a layered PSD

Post by Mike Hale »

In the meantime here are two functions for you. Put them near the top of the script with the other functions.

Code: Select allquickMaskMode = function(bool) {
   var mode =  "Cler";
   if(bool){
   var mode = "setd";
      }
    var desc = new ActionDescriptor();
   var ref = new ActionReference();
   ref.putProperty( charIDToTypeID( "Prpr" ), charIDToTypeID( "QucM" ) );
   ref.putEnumerated( charIDToTypeID( "Dcmn" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
    desc.putReference( charIDToTypeID( "null" ), ref );
   executeAction( charIDToTypeID( mode ), desc, DialogModes.NO );
}
applyThreshold = function(amount) {
   if((amount < 0) || (amount > 256)){
   return;
   }
    var desc = new ActionDescriptor();
    desc.putInteger( charIDToTypeID( "Lvl " ), amount );
   executeAction( charIDToTypeID( "Thrs" ), desc, DialogModes.NO );
}

Then I think you will want to add this somewhere in the for loop.

Code: Select allquickMaskMode(true);
applyThreshold(128);
quickMaskMode(false);


And you may need to invert the selection at some point

Mike
paPus

removing unwanted pixels from a layered PSD

Post by paPus »

Code: Select all   Layer2Selection = function()
   {
      if( app.activeDocument.activeLayer.isBackgroundLayer ) return

      var desc   = new ActionDescriptor()
      var ref      = new ActionReference()
      ref.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) )
      desc.putReference( charIDToTypeID( "null" ), ref )
      var ref1   = new ActionReference()
      ref1.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) )
      desc.putReference( charIDToTypeID( "T   " ), ref1 )
      executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO )
   }

   AddLayer2Selection = function()
   {
      if( app.activeDocument.activeLayer.isBackgroundLayer ) return

      var desc   = new ActionDescriptor()
      var ref      = new ActionReference()
      ref.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ) , charIDToTypeID( "Trsp" ) )
      desc.putReference( charIDToTypeID( "null" ), ref )
      var ref1   = new ActionReference()
      ref1.putProperty( charIDToTypeID( "Chnl" ), charIDToTypeID( "fsel" ) )
      desc.putReference( charIDToTypeID( "T   " ), ref1 )
      executeAction( charIDToTypeID( "Add " ), desc, DialogModes.NO )
   }

   var doc          = activeDocument
   var layersToClip   = doc.artLayers.length - 1      // don't count the background
   doc.crop([0, 0, doc.width, doc.height])            // clear everything that is outside of the document's boundaries

   doc.activeLayer      = doc.artLayers[0]            // start with top layer
   Layer2Selection()                                 // and make the first selection

   for( i = 1; i < layersToClip; i++)               // don't cound the top layer
   {
      doc.activeLayer = doc.artLayers            // switch to next layer
      activeDocument.quickMaskMode = true            // set the QuickMask mode
      activeDocument.activeLayer.threshold(128)      // apply a mid grey threshold
      activeDocument.quickMaskMode = false            // and get out of the QM mode
      doc.selection.clear()                           // clear the layer of unwanted pixels
      AddLayer2Selection()                           // add remaining pixels to the selection
   }

   doc.selection.deselect()                           // and clear the traces
   doc.activeLayer = doc.artLayers[0]               // and select the top layer
Thank you very much Mike!
i've modified your code, here it is.
I've also added a crop, to delete everything outside the boundaries, and deleted the add quickmask and the threshold, since they are included in the JS.

Now it's working perfectly for me
(i have some time now, untill now i didn't that's why i didn't respond)
it's a pitty, that the tabs are converted to spaces, even though the