Copy link to clipboard
Copied
Hi everyone. I really need your help. I'm trying to find a script that can convert all alpha channels into different layers and if one or more alpha channels is/are empty/black to be deleted.
Thank you
You are right, Apply Image might also be faster.
// create layers for channels that are not empty in rgb images;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
if (activeDocument.mode == DocumentMode.RGB) {
var theChannels = collectChannels ();
activeDocument.selection.deselect();
// create layers;
for (var m = theChannels.length-1; m >= 0; m--) {
loadAndLayer (theChannels[m][1], theChannels[m][0], [0,0,0]);
};
};
};
////// collect layers //////
function collectChannels () {
/
...
Copy link to clipboard
Copied
Could you please post a screenshot with the pertinent Panels (Toolbar, Layers, Channels, Options Bar, …) visible for the source and the intended result?
Copy link to clipboard
Copied
Alpha channels are like selection and layer mask a gray scale channel. All white would be like a select all black like no selection. Converted to a layer they would Gray scale images that have three channel RGB if the document mode is RGB. One would Target an alpha select all copy to the clipboard and paste in a layer that you should mate tp be associated with the Alpha channel. You would still have up to 53 Alpha channels and up to 53 additional RGB images layers. Would you also want the alpha channels deleted? Or do you was soe other kinf of conversion? Why do you need to convert a channel to an image layer? Hers a Loade and imags lunionsity as as slecetion. Is saved the selection as Alpha Image Lininiosity. It targeted the Alpjt channel. Then did menu Select all, Menu edit>copy Menu edit>Paste. You can see Layer 1 looks like Alpha Image Luminisoty and has a Red Green and Blue channel. I just don't undetstand what reasion the woul be to do duch a thing.
Copy link to clipboard
Copied
// create layers for channels that are not empty;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
var theChannels = collectChannels ();
// create layers;
for (var m = theChannels.length-1; m >= 0; m--) {
loadAndLayer (theChannels[m][1], theChannels[m][0], [0,0,0]);
};
};
////// collect layers //////
function collectChannels () {
// get number of layers;
var ref = new ActionReference();
//ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfChannels'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfChannels"));
// pixel dimensions;
var theWidth = applicationDesc.getUnitDoubleValue(stringIDToTypeID("width"));
var theHeight = applicationDesc.getUnitDoubleValue(stringIDToTypeID("height"));
var theRes = applicationDesc.getUnitDoubleValue(stringIDToTypeID("resolution"));
var thePixels = (theWidth*theRes/72)*(theHeight*theRes/72);
// process the channels;
var theChannels = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex(stringIDToTypeID( "channel" ), m);
var channelDesc = executeActionGet(ref);
// collect values;
var theName = channelDesc.getString(stringIDToTypeID('channelName'));
var theIndex = channelDesc.getInteger(stringIDToTypeID('itemIndex'));
var theID = channelDesc.getInteger(stringIDToTypeID('ID'));
if (channelDesc.hasKey(stringIDToTypeID('alphaChannelOptions')) == true) {
var theHistogram = channelDesc.getList(stringIDToTypeID('histogram'));
var value0 = theHistogram.getInteger(0);
// if not completely black;
if (value0 != thePixels) {
theChannels.push([theName, theIndex, theID])
} else {}
};
} catch (e) {};
};
return theChannels
};
//////
function loadAndLayer (identifier, theName, theColor) {
var idnull = stringIDToTypeID( "null" );
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idchannel = stringIDToTypeID( "channel" );
// =======================================================
var desc10 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putProperty( idchannel, stringIDToTypeID( "selection" ) );
desc10.putReference( idnull, ref2 );
var ref3 = new ActionReference();
ref3.putIndex( idchannel, identifier );
desc10.putReference( stringIDToTypeID( "to" ), ref3 );
executeAction( stringIDToTypeID( "set" ), desc10, DialogModes.NO );
// =======================================================
var desc11 = new ActionDescriptor();
var ref4 = new ActionReference();
ref4.putClass( idcontentLayer );
desc11.putReference( idnull, ref4 );
var desc12 = new ActionDescriptor();
var desc13 = new ActionDescriptor();
var desc14 = new ActionDescriptor();
desc14.putDouble( stringIDToTypeID( "red" ), theColor[0] );
desc14.putDouble( stringIDToTypeID( "grain" ), theColor[1] );
desc14.putDouble( stringIDToTypeID( "blue" ), theColor[2] );
var idRGBColor = stringIDToTypeID( "RGBColor" );
desc13.putObject( stringIDToTypeID( "color" ), idRGBColor, desc14 );
desc12.putString( stringIDToTypeID( "name" ), theName );
desc12.putObject( stringIDToTypeID( "type" ), stringIDToTypeID( "solidColorLayer" ), desc13 );
desc11.putObject( stringIDToTypeID( "using" ), idcontentLayer, desc12 );
executeAction( stringIDToTypeID( "make" ), desc11, DialogModes.NO );
};
Copy link to clipboard
Copied
What should I do to run your script without error on this line:
var channelDesc = executeActionGet(ref);
Copy link to clipboard
Copied
Well, I may have done insuffiient testing – just plain RGB images with alpha-channels, spot channel, …
Could you post a screenshot of the Channels Panel for the file with which this error occurs?
And I didn’t use the putProperty-technique here because I wanted to retrieve more than just the
numberOfChannels
but also the image’s dimensions.
Edit:
Copy link to clipboard
Copied
I created new document, made background, then added layerSet, in layerSet I added Red ColorFill Adjustement Layer, then made square selection somewhere within document and made a mask from that selection for layerSet. That resulted in error. After I added some Alpha channel I got error again. Maybe tell me by steps what to create in document, to run script without error?
Copy link to clipboard
Copied
The first time I ran the script it failed in the last line Make was not available. I was playing with alpha channels and the last one was the current target when I ran the script. I added a select RGB right after the test to see if the was a document it fixes the problem thet alpha channel beint the targer cxaused..
Copy link to clipboard
Copied
Thanks for the feedback, Kukurykus and JJMack.
Apparently the composite channels need to be selected, I hope this amendment fixes the issue.
// create layers for channels that are not empty in rgb images;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
if (activeDocument.mode == DocumentMode.RGB) {
var theChannels = collectChannels ();
// create layers;
for (var m = theChannels.length-1; m >= 0; m--) {
loadAndLayer (theChannels[m][1], theChannels[m][0], [0,0,0]);
};
};
};
////// collect layers //////
function collectChannels () {
// get number of layers;
var ref = new ActionReference();
//ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfChannels'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfChannels"));
// pixel dimensions;
var theWidth = applicationDesc.getUnitDoubleValue(stringIDToTypeID("width"));
var theHeight = applicationDesc.getUnitDoubleValue(stringIDToTypeID("height"));
var theRes = applicationDesc.getUnitDoubleValue(stringIDToTypeID("resolution"));
var thePixels = (theWidth*theRes/72)*(theHeight*theRes/72);
// process the channels;
var theChannels = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex(stringIDToTypeID( "channel" ), m);
var channelDesc = executeActionGet(ref);
// collect values;
var theName = channelDesc.getString(stringIDToTypeID('channelName'));
var theIndex = channelDesc.getInteger(stringIDToTypeID('itemIndex'));
var theID = channelDesc.getInteger(stringIDToTypeID('ID'));
if (channelDesc.hasKey(stringIDToTypeID('alphaChannelOptions')) == true) {
var theHistogram = channelDesc.getList(stringIDToTypeID('histogram'));
var value0 = theHistogram.getInteger(0);
// if not completely black;
if (value0 != thePixels) {
theChannels.push([theName, theIndex, theID])
} else {}
};
} catch (e) {};
};
return theChannels
};
//////
function loadAndLayer (identifier, theName, theColor) {
var idnull = stringIDToTypeID( "null" );
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idchannel = stringIDToTypeID( "channel" );
// =======================================================
var desc2 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putEnumerated( idchannel, idchannel, stringIDToTypeID( "RGB" ) );
desc2.putReference( idnull, ref1 );
executeAction( stringIDToTypeID( "select" ), desc2, DialogModes.NO );
// =======================================================
var desc10 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putProperty( idchannel, stringIDToTypeID( "selection" ) );
desc10.putReference( idnull, ref2 );
var ref3 = new ActionReference();
ref3.putIndex( idchannel, identifier );
desc10.putReference( stringIDToTypeID( "to" ), ref3 );
executeAction( stringIDToTypeID( "set" ), desc10, DialogModes.NO );
// =======================================================
var desc11 = new ActionDescriptor();
var ref4 = new ActionReference();
ref4.putClass( idcontentLayer );
desc11.putReference( idnull, ref4 );
var desc12 = new ActionDescriptor();
var desc13 = new ActionDescriptor();
var desc14 = new ActionDescriptor();
desc14.putDouble( stringIDToTypeID( "red" ), theColor[0] );
desc14.putDouble( stringIDToTypeID( "grain" ), theColor[1] );
desc14.putDouble( stringIDToTypeID( "blue" ), theColor[2] );
var idRGBColor = stringIDToTypeID( "RGBColor" );
desc13.putObject( stringIDToTypeID( "color" ), idRGBColor, desc14 );
desc12.putString( stringIDToTypeID( "name" ), theName );
desc12.putObject( stringIDToTypeID( "type" ), stringIDToTypeID( "solidColorLayer" ), desc13 );
desc11.putObject( stringIDToTypeID( "using" ), idcontentLayer, desc12 );
executeAction( stringIDToTypeID( "make" ), desc11, DialogModes.NO );
};
Copy link to clipboard
Copied
I did the same what I described and used new version of script and I'm getting same error.
Copy link to clipboard
Copied
Could you please post a screenshot of the Channels and Layers Panels at the moment of the fail happening?
So far I cannot figure out what would cause the fail with the current code.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks again to both of you.
I just cannot reproduce the error.
The Script should disregard Layer Masks and if there is no alpha channel or spot channel it should not perform anything, but it should certainly not throw an error …
Copy link to clipboard
Copied
Finally I was able to make it to work. I didn't need it, just was interested in effect but thx for help 😉
Copy link to clipboard
Copied
But as the original poster apparently hasn’t added anything since the original post it seems like an academic discussion amongst Forum regulars anyway …
Copy link to clipboard
Copied
When I used to solve more user problems I often met such users. Stephen_A_Marsh finds it as a way to get new experience for problem he could't find himself. As you see for some of us it's still okey, including me in past 😉
Copy link to clipboard
Copied
Hi everyone. Sorry for the late responce (home sick 😞 ). I've tested the script and it's working perfectly, but i have change the way I'm rendering the images (from 3ds max) in defferent way, because most of my scenes are with more than 53 alpha masks, but still I will use the script :). Thank you very much.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Good point!
As the Script uses an intermediary Selection and Selections are only 8bit in Photoshop so far the Script would waste a lot of 16bit or 32bit data.
To circumvent that one would probably need to copy/paste the Channels to the Layer Masks which might slow things down noticably.
zlatkoz26887948, I hope your recovery goes well!
Copy link to clipboard
Copied
It’s best to use the “Apply Image” command.
Copy link to clipboard
Copied
You are right, Apply Image might also be faster.
// create layers for channels that are not empty in rgb images;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
if (activeDocument.mode == DocumentMode.RGB) {
var theChannels = collectChannels ();
activeDocument.selection.deselect();
// create layers;
for (var m = theChannels.length-1; m >= 0; m--) {
loadAndLayer (theChannels[m][1], theChannels[m][0], [0,0,0]);
};
};
};
////// collect layers //////
function collectChannels () {
// get number of layers;
var ref = new ActionReference();
//ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfChannels'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfChannels"));
// pixel dimensions;
var theWidth = applicationDesc.getUnitDoubleValue(stringIDToTypeID("width"));
var theHeight = applicationDesc.getUnitDoubleValue(stringIDToTypeID("height"));
var theRes = applicationDesc.getUnitDoubleValue(stringIDToTypeID("resolution"));
var thePixels = (theWidth*theRes/72)*(theHeight*theRes/72);
// process the channels;
var theChannels = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex(stringIDToTypeID( "channel" ), m);
var channelDesc = executeActionGet(ref);
// collect values;
var theName = channelDesc.getString(stringIDToTypeID('channelName'));
var theIndex = channelDesc.getInteger(stringIDToTypeID('itemIndex'));
var theID = channelDesc.getInteger(stringIDToTypeID('ID'));
if (channelDesc.hasKey(stringIDToTypeID('alphaChannelOptions')) == true) {
var theHistogram = channelDesc.getList(stringIDToTypeID('histogram'));
var value0 = theHistogram.getInteger(0);
// if not completely black;
if (value0 != thePixels) {
theChannels.push([theName, theIndex, theID])
} else {}
};
} catch (e) {};
};
return theChannels
};
//////
function loadAndLayer (theIndex, theName, theColor) {
var idnull = stringIDToTypeID( "null" );
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idchannel = stringIDToTypeID( "channel" );
var idmake = stringIDToTypeID( "make" );
// =======================================================
var desc11 = new ActionDescriptor();
var ref4 = new ActionReference();
ref4.putClass( idcontentLayer );
desc11.putReference( idnull, ref4 );
var desc12 = new ActionDescriptor();
var desc13 = new ActionDescriptor();
var desc14 = new ActionDescriptor();
desc14.putDouble( stringIDToTypeID( "red" ), theColor[0] );
desc14.putDouble( stringIDToTypeID( "grain" ), theColor[1] );
desc14.putDouble( stringIDToTypeID( "blue" ), theColor[2] );
var idRGBColor = stringIDToTypeID( "RGBColor" );
desc13.putObject( stringIDToTypeID( "color" ), idRGBColor, desc14 );
desc12.putString( stringIDToTypeID( "name" ), theName );
desc12.putObject( stringIDToTypeID( "type" ), stringIDToTypeID( "solidColorLayer" ), desc13 );
desc11.putObject( stringIDToTypeID( "using" ), idcontentLayer, desc12 );
executeAction( idmake, desc11, DialogModes.NO );
// =======================================================
var desc2 = new ActionDescriptor();
desc2.putClass( stringIDToTypeID( "new" ), idchannel );
var ref1 = new ActionReference();
ref1.putEnumerated( idchannel, idchannel, idmask = stringIDToTypeID( "mask" ) );
desc2.putReference( stringIDToTypeID( "at" ), ref1 );
desc2.putEnumerated( stringIDToTypeID( "using" ), stringIDToTypeID( "userMaskEnabled" ), stringIDToTypeID( "hideAll" ) );
executeAction( idmake, desc2, DialogModes.NO );
// =======================================================
var desc3 = new ActionDescriptor();
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putIndex( idchannel, theIndex );
desc4.putReference( stringIDToTypeID( "to" ), ref2 );
var idpreserveTransparency = stringIDToTypeID( "preserveTransparency" );
desc4.putBoolean( idpreserveTransparency, true );
desc3.putObject( stringIDToTypeID( "with" ), stringIDToTypeID( "calculation" ), desc4 );
executeAction( idapplyImageEvent = stringIDToTypeID( "applyImageEvent" ), desc3, DialogModes.NO );
};
Copy link to clipboard
Copied
This script always fails in line 79 on my system even with a simple test.
Copy link to clipboard
Copied
Good catch!
I have »Use Default Masks on Fill Layers« turned off so the Fill Layer is create without a Layer Mask here …
// create layers for channels that are not empty in rgb images;
// 2020, use it at your own risk;
if (app.documents.length > 0) {
if (activeDocument.mode == DocumentMode.RGB) {
var theChannels = collectChannels ();
activeDocument.selection.deselect();
// create layers;
for (var m = theChannels.length-1; m >= 0; m--) {
loadAndLayer (theChannels[m][1], theChannels[m][0], [0,0,0]);
};
};
};
////// collect layers //////
function collectChannels () {
// get number of layers;
var ref = new ActionReference();
//ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfChannels'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfChannels"));
// pixel dimensions;
var theWidth = applicationDesc.getUnitDoubleValue(stringIDToTypeID("width"));
var theHeight = applicationDesc.getUnitDoubleValue(stringIDToTypeID("height"));
var theRes = applicationDesc.getUnitDoubleValue(stringIDToTypeID("resolution"));
var thePixels = (theWidth*theRes/72)*(theHeight*theRes/72);
// process the channels;
var theChannels = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex(stringIDToTypeID( "channel" ), m);
var channelDesc = executeActionGet(ref);
// collect values;
var theName = channelDesc.getString(stringIDToTypeID('channelName'));
var theIndex = channelDesc.getInteger(stringIDToTypeID('itemIndex'));
var theID = channelDesc.getInteger(stringIDToTypeID('ID'));
if (channelDesc.hasKey(stringIDToTypeID('alphaChannelOptions')) == true) {
var theHistogram = channelDesc.getList(stringIDToTypeID('histogram'));
var value0 = theHistogram.getInteger(0);
// if not completely black;
if (value0 != thePixels) {
theChannels.push([theName, theIndex, theID])
} else {}
};
} catch (e) {};
};
return theChannels
};
//////
function loadAndLayer (theIndex, theName, theColor) {
var idnull = stringIDToTypeID( "null" );
var idcontentLayer = stringIDToTypeID( "contentLayer" );
var idchannel = stringIDToTypeID( "channel" );
var idmake = stringIDToTypeID( "make" );
// =======================================================
var desc11 = new ActionDescriptor();
var ref4 = new ActionReference();
ref4.putClass( idcontentLayer );
desc11.putReference( idnull, ref4 );
var desc12 = new ActionDescriptor();
var desc13 = new ActionDescriptor();
var desc14 = new ActionDescriptor();
desc14.putDouble( stringIDToTypeID( "red" ), theColor[0] );
desc14.putDouble( stringIDToTypeID( "grain" ), theColor[1] );
desc14.putDouble( stringIDToTypeID( "blue" ), theColor[2] );
var idRGBColor = stringIDToTypeID( "RGBColor" );
desc13.putObject( stringIDToTypeID( "color" ), idRGBColor, desc14 );
desc12.putString( stringIDToTypeID( "name" ), theName );
desc12.putObject( stringIDToTypeID( "type" ), stringIDToTypeID( "solidColorLayer" ), desc13 );
desc11.putObject( stringIDToTypeID( "using" ), idcontentLayer, desc12 );
executeAction( idmake, desc11, DialogModes.NO );
// remove layer mask;
try {
// =======================================================
var desc10 = new ActionDescriptor();
var ref2 = new ActionReference();
var idchannel = stringIDToTypeID( "channel" );
ref2.putEnumerated( idchannel, idchannel, stringIDToTypeID( "mask" ) );
desc10.putReference( stringIDToTypeID( "null" ), ref2 );
executeAction( stringIDToTypeID( "delete" ), desc10, DialogModes.NO );
} catch (e) {};
// =======================================================
var desc2 = new ActionDescriptor();
desc2.putClass( stringIDToTypeID( "new" ), idchannel );
var ref1 = new ActionReference();
ref1.putEnumerated( idchannel, idchannel, idmask = stringIDToTypeID( "mask" ) );
desc2.putReference( stringIDToTypeID( "at" ), ref1 );
desc2.putEnumerated( stringIDToTypeID( "using" ), stringIDToTypeID( "userMaskEnabled" ), stringIDToTypeID( "hideAll" ) );
executeAction( idmake, desc2, DialogModes.NO );
// =======================================================
var desc3 = new ActionDescriptor();
var desc4 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putIndex( idchannel, theIndex );
desc4.putReference( stringIDToTypeID( "to" ), ref2 );
var idpreserveTransparency = stringIDToTypeID( "preserveTransparency" );
desc4.putBoolean( idpreserveTransparency, true );
desc3.putObject( stringIDToTypeID( "with" ), stringIDToTypeID( "calculation" ), desc4 );
executeAction( idapplyImageEvent = stringIDToTypeID( "applyImageEvent" ), desc3, DialogModes.NO );
};
edited
Copy link to clipboard
Copied
now it fails in line 88
Copy link to clipboard
Copied
If you are still willing to test it I think I found the problem and updated the code on the previous post.