Copy link to clipboard
Copied
Hello,
My script works as expected, but the problem is when it fills on a locked transparency, the dialog box pops up, which is not what I want.
I see some very old answers that say to use AM code, but i can't understand how it works and I don't know how to adapt it to the code I've written.
function reColorGroup (tag, colorObject, styleString) {
var doc = app.activeDocument;
var group = doc.layerSets.getByName(tag+"-"+styleString);
var color = new SolidColor();
doc.activeLayer = group.layers.getByName("BASE");
doc.activeLayer.visible = true;
color.rgb.hexValue = colorObject.color;
doc.selection.fill(color);
}
Here's the two leads I found:
https://stackoverflow.com/questions/23699937/photoshop-opens-dialog-box-when-trying-to-fill-a-layer-...
I appreciate any help. Thank you.
Copy link to clipboard
Copied
Adobe has a Photoshop plug-in named ScriptListener. This plug-in is like an Action recorder it records Photoshop Steps you do in Photoshop. However, it does not create actions. It just logs the steps in two log file on your desktop. One log is in JavaScript code the other log in VBS code. It not very readable. However, it can be used in your script instead of the DOM code you currently have for fill.
doc.selection.fill(color);
Basically you are filling an active current selection in the Active Layer in the active document if your doc is the active document. that is app.activeDocument.selection.fill(Color) so you need the Action manager code equivalent.
The code found was close.
app.activeDocument.selection.fill(app.foregroundColor);
// =======================================================
var idFl = charIDToTypeID( "Fl " );
var desc18 = new ActionDescriptor();
var idUsng = charIDToTypeID( "Usng" );
var idFlCn = charIDToTypeID( "FlCn" );
var idFrgC = charIDToTypeID( "FrgC" );
desc18.putEnumerated( idUsng, idFlCn, idFrgC );
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc18.putUnitDouble( idOpct, idPrc, 100.000000 );
var idMd = charIDToTypeID( "Md " );
var idBlnM = charIDToTypeID( "BlnM" );
var idNrml = charIDToTypeID( "Nrml" );
desc18.putEnumerated( idMd, idBlnM, idNrml );
var idPrsT = charIDToTypeID( "PrsT" );
desc18.putBoolean( idPrsT, true );
executeAction( idFl, desc18, DialogModes.NO );
The Problem is the scriptlistener code is like action steps which have hard coded settings. They get away with it for they are filling with the foreground color which they can change first. You need to be able to pass the Color and its opacity. You would need to turn the Action Manager code into a function the has parameters.
Here is what the Action manager code would look like for a red fill normal mode 100% opacity.
// =======================================================
var idFl = charIDToTypeID( "Fl " );
var desc27 = new ActionDescriptor();
var idUsng = charIDToTypeID( "Usng" );
var idFlCn = charIDToTypeID( "FlCn" );
var idClr = charIDToTypeID( "Clr " );
desc27.putEnumerated( idUsng, idFlCn, idClr );
var idClr = charIDToTypeID( "Clr " );
var desc28 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc28.putDouble( idRd, 255.000000 );
var idGrn = charIDToTypeID( "Grn " );
desc28.putDouble( idGrn, 0.000000 );
var idBl = charIDToTypeID( "Bl " );
desc28.putDouble( idBl, 0.000000 );
var idRGBC = charIDToTypeID( "RGBC" );
desc27.putObject( idClr, idRGBC, desc28 );
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc27.putUnitDouble( idOpct, idPrc, 100.000000 );
var idMd = charIDToTypeID( "Md " );
var idBlnM = charIDToTypeID( "BlnM" );
var idNrml = charIDToTypeID( "Nrml" );
desc27.putEnumerated( idMd, idBlnM, idNrml );
executeAction( idFl, desc27, DialogModes.NO );
Not very readable. There is a script "Clean SL" that can clean that up make it more readable and convert it to code and functions.
// =======================================================
fill(255, 0, 0, 100);
function fill(red, Grn, blue, opacity) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor.putEnumerated( stringIDToTypeID( "using" ), stringIDToTypeID( "fillContents" ), stringIDToTypeID( "color" ));
descriptor2.putDouble( stringIDToTypeID( "red" ), red );
descriptor2.putDouble( charIDToTypeID( "Grn " ), Grn );
descriptor2.putDouble( stringIDToTypeID( "blue" ), blue );
descriptor.putObject( stringIDToTypeID( "color" ), stringIDToTypeID( "RGBColor" ), descriptor2 );
descriptor.putUnitDouble( stringIDToTypeID( "opacity" ), stringIDToTypeID( "percentUnit" ), opacity );
descriptor.putEnumerated( stringIDToTypeID( "mode" ), stringIDToTypeID( "blendMode" ), stringIDToTypeID( "normal" ));
executeAction( stringIDToTypeID( "fill" ), descriptor, DialogModes.NO );
Copy link to clipboard
Copied
Thanks for the insight. do you have some idea how to do this action manager code to fill a hex value instead of the rgb? I'm pulling the hex values from another source so I don't know how i could switch it to the rgb values.
Actually I decided to run with your fill using rgb. It works until I get to a layer with locked transparency, and then it says Error 8800 General Photoshop Error Occurred, The Parameters for Fill are not valid.
Copy link to clipboard
Copied
If you can not figure that out from what I posted. I can not help I just hack at scripting you need to pass your color three values color.red color.green and color .blue and 100
Copy link to clipboard
Copied
Thanks, just decided to work with your code. any insight on this error 8800?
Copy link to clipboard
Copied
Ok, I got around it by copy paste from the script listener and just selecting the transparent pixels (have to unlock, select, fill, deselect, lock). It's ugly but it works.
Copy link to clipboard
Copied
doc.selection.fill(color, undefined, undefined, true);