Copy link to clipboard
Copied
Hello,
I am completely new into scripting for photoshop and I am looking for the following:
I have a document with 81 layers, each containing one rectangle. Through a popup/prompt screen I would like to set the lab value of my first layer/rectangle.
Based on this "master value" the script needs to add 0,1 on the L value of each layer/rectangle e.g
Prompt L =10,00
A = 10,00
B =10,00
Rectangle1 L=10,00, A = 10,00, B= 10,00
Rectangle2 L=10,10, A = 10,00, B= 10,00
Rectangle3 L=10,20, A = 10,00, B= 10,00
Rectangle4 L=10,30, A = 10,00, B= 10,00
...
Rectangle81
Is there somebody who can help me out here?
Thanks in advance!
Hi Chuck Uebele​,
nice try.
But the example file has shape layers. Your code works with pixel layers only.
IMHO dennism44706796 needs something more like this
...// fillColor_setFillColorOfShapeLayer_withPrompt.jsx
// https://forums.adobe.com/thread/2254273
// regards pixxxel schubser
// Dec. 2016
// document needs the same structure like example file
var aDoc = app.activeDocument;
var Len = aDoc.layers.length;
aDoc.activeLayer = aDoc.layers[Len-2];
main ();
function main() {
var prmt = prompt ("L 0...100
Copy link to clipboard
Copied
Hi,
there are pixel or vector rectangles?
Can you upload an example file please?
Copy link to clipboard
Copied
Hi,
many thanks for your reaction.
You can download the file from the following link:
I just used the rectangle tool from the console the make the rectangle shapes.
Copy link to clipboard
Copied
One question:
You know that L value required an integer value?
Copy link to clipboard
Copied
Hi again,
I found a code which might be used as little workaround:
// create a document reference to work with
var doc = app.activeDocument;
//define the path
var lineArray = new Array();
lineArray[0] = new PathPointInfo;
lineArray[0].kind = PointKind.CORNERPOINT;
lineArray[0].anchor = Array(100, 100);//top left
lineArray[0].leftDirection = lineArray[0].anchor;
lineArray[0].rightDirection = lineArray[0].anchor;
lineArray[1] = new PathPointInfo;
lineArray[1].kind = PointKind.CORNERPOINT;
lineArray[1].anchor = Array(200, 100);//top right
lineArray[1].leftDirection = lineArray[1].anchor;
lineArray[1].rightDirection = lineArray[1].anchor;
lineArray[2] = new PathPointInfo;
lineArray[2].kind = PointKind.CORNERPOINT;
lineArray[2].anchor = Array(200, 900);//bottom right
lineArray[2].leftDirection = lineArray[2].anchor;
lineArray[2].rightDirection = lineArray[2].anchor;
lineArray[3] = new PathPointInfo;
lineArray[3].kind = PointKind.CORNERPOINT;
lineArray[3].anchor = Array(100, 900);//bottom left
lineArray[3].leftDirection = lineArray[3].anchor;
lineArray[3].rightDirection = lineArray[3].anchor;
var lineSubPathArray = new Array();
lineSubPathArray[0] = new SubPathInfo();
lineSubPathArray[0].operation = ShapeOperation.SHAPEADD;
lineSubPathArray[0].closed = true;
lineSubPathArray[0].entireSubPath = lineArray;
// now make the path
var myPathItem = doc.pathItems.add("rect1", lineSubPathArray);
// make the layer using scriptlistner
//because is seems the guide is wrong you can only set
//the layerkind to text or normal
//if the path is active as it is now, photoshop uses it as a mask
var desc88 = new ActionDescriptor();
var ref60 = new ActionReference();
ref60.putClass( stringIDToTypeID( "contentLayer" ) );
desc88.putReference( charIDToTypeID( "null" ), ref60 );
var desc89 = new ActionDescriptor();
var desc90 = new ActionDescriptor();
var desc91 = new ActionDescriptor();
desc91.putDouble( charIDToTypeID( "Rd " ), 239.000000 );//change these to change color
desc91.putDouble( charIDToTypeID( "Grn " ), 12.000000 );
desc91.putDouble( charIDToTypeID( "Bl " ), 12.000000 );
var id481 = charIDToTypeID( "RGBC" );
desc90.putObject( charIDToTypeID( "Clr " ), id481, desc91 );
desc89.putObject( charIDToTypeID( "Type" ), stringIDToTypeID( "solidColorLayer" ), desc90 );
desc88.putObject( charIDToTypeID( "Usng" ), stringIDToTypeID( "contentLayer" ), desc89 );
executeAction( charIDToTypeID( "Mk " ), desc88, DialogModes.NO );
//remove the path
myPathItem.remove();
I only don't know which code to use to replace the RGB input in to LAB values input(i marked this part in bold). Do you have any idea?
In stead of changing the LAB values of the existing layers, i can than also create a loop to make and organise all squares like in the example file and use a prompt line for the specific LAB value ...
Copy link to clipboard
Copied
Hi,
the code you 've posted is not the problem. But it seems you didn't read my last question carefully:
pixxxel schubser schrieb:
One question:
You know that L value required an integer value?
IMHO it is not possible in PS to use values like 10,1 or 11,2 for the luminance. Only 10 or 11
Copy link to clipboard
Copied
Hi Again,
sorry it seems misunderstood. I was not aware of this...
However, the code will also help me alot when using steps of 1 integer value as you stated above 10, 11, 12, ...
Copy link to clipboard
Copied
Just to give you a little more background info. in the end I would like to generate a file like the picture below:
So once I fill in my master LAB value, the code will do - and + 1 on all the L, A, & B values, to create a colour variation matrix.
Copy link to clipboard
Copied
I thought already.
And in this case you have to use the Ranges for L and a and b which are possible in PS
L 0 ... 100
a -128 ... 127
b -128 ... 127
Copy link to clipboard
Copied
If you use L*A*B* in 16 bit color, you can use non-integer values. I did a little test. The below script will set the foreground color and read spot in an open image back to the ESTK console. I can get non integer values.
#target photoshop
var doc = activeDocument;
var x=50;
var y=40;
var foregroundC = new SolidColor();
foregroundC.lab.l =80.8888;
foregroundC.lab.a = 60.555;
foregroundC.lab.b = -33.444;
foregroundColor = foregroundC;
fillForeground ()
$.writeln(getColor (x, y,'lab'));
//alert(colorArray[0]+'\n'+colorArray[1]+'\n'+colorArray[2])
function getColor(xLoc, yLoc, cSpace){
doc.colorSamplers.removeAll();
var locArray = [xLoc,yLoc];
var sColor = doc.colorSamplers.add(locArray);
switch(cSpace){
case 'rgb':
var colorArray = [sColor.color.rgb.red, sColor.color.rgb.green,sColor.color.rgb.blue];
break;
case 'cmyk':
var colorArray = [sColor.color.cmyk.cyan, sColor.color.cmyk.magenta,sColor.color.cmyk.yellow,sColor.color.cmyk.black];
break;
case 'lab':
var colorArray = [sColor.color.lab.l, sColor.color.lab.a,sColor.color.lab.b];
break;
case 'hsb':
var colorArray = [sColor.color.hsb.hue, sColor.color.hsb.saturation,sColor.color.hsb.brightness];
break;
};//end switch
return colorArray;
}
function fillForeground(){
var idFl = charIDToTypeID( "Fl " );
var desc2 = new ActionDescriptor();
var idUsng = charIDToTypeID( "Usng" );
var idFlCn = charIDToTypeID( "FlCn" );
var idFrgC = charIDToTypeID( "FrgC" );
desc2.putEnumerated( idUsng, idFlCn, idFrgC );
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc2.putUnitDouble( idOpct, idPrc, 100.000000 );
var idMd = charIDToTypeID( "Md " );
var idBlnM = charIDToTypeID( "BlnM" );
var idNrml = charIDToTypeID( "Nrml" );
desc2.putEnumerated( idMd, idBlnM, idNrml );
executeAction( idFl, desc2, DialogModes.NO );
}
Copy link to clipboard
Copied
Hi Chuck Uebele​,
nice try.
But the example file has shape layers. Your code works with pixel layers only.
IMHO dennism44706796 needs something more like this
// fillColor_setFillColorOfShapeLayer_withPrompt.jsx
// https://forums.adobe.com/thread/2254273
// regards pixxxel schubser
// Dec. 2016
// document needs the same structure like example file
var aDoc = app.activeDocument;
var Len = aDoc.layers.length;
aDoc.activeLayer = aDoc.layers[Len-2];
main ();
function main() {
var prmt = prompt ("L 0...100,\na -128...127,\nb -128...127", "50,0,0", "LAB-Werte eingeben");
if (prmt) {
arr = prmt.split(",");
} else {
alert ("cancelled");
return;
}
var sColor = new SolidColor;
sColor.lab.l = eval(arr[0]);
sColor.lab.a = eval(arr[1]);
sColor.lab.b = eval(arr[2]);
if (sColor.lab.l + Len > 100) {
alert ("The last " + (sColor.lab.l + (Len -1) - 100) + " layers will have same color.");
}
for (x=Len-2; x>=0; x--) {
aDoc.activeLayer = aDoc.layers
; setNewColor2Shape( sColor );
sColor.lab.l ++;
if (x%10 == 0) {
app.refresh();
}
}
}
function setNewColor2Shape( sColor ) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( stringIDToTypeID( "contentLayer" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
desc.putReference( charIDToTypeID( "null" ), ref );
var theFillColor = new ActionDescriptor();
var colorValue = new ActionDescriptor();
colorValue.putDouble( charIDToTypeID("Lmnc"), sColor.lab.l);
colorValue.putDouble( charIDToTypeID("A "), sColor.lab.a);
colorValue.putDouble( charIDToTypeID("B "), sColor.lab.b);
theFillColor.putObject( charIDToTypeID( "Clr " ), charIDToTypeID( "LbCl" ), colorValue );
desc.putObject( charIDToTypeID( "T " ), stringIDToTypeID( "solidColorLayer" ), theFillColor );
executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );
}
Have fun
Copy link to clipboard
Copied
Yea, I was just showing that you could get non-integer values, not so much on creating the shapes and filling them.
Copy link to clipboard
Copied
Hey Guys,
First of all merry Christmas to both of you and thank you very much for all the help !
pixxxel schubser​, your code works perfect, thanks for that! I am very interested in the option of Chuck Uebele​ too, as it can/might give me a more accurate matrix in the end. But let's focus first on the code of pixxxel schubser​.
I've been thinking and the more I look at the picture I send earlier i think this colour matrix goes like :
Is this kind of matrix possible when using script?
Copy link to clipboard
Copied
The Question in your first post is answered?
Are there helpful or correct answers for you in this thread? Please marks them.
- - - - - - - - - - - - - - - - - -
The questions in your post #12 are much more complex. Perhaps time for a new thread?
Perhaps you find someone who is writing the script for you.
Possible with [JS]
But three things:
PS supported IMHO 8000 layers (as maximum)
Working with shapes in PS is very time expensive
The more layers in PS you have, the much much much more time you need (not proportionally - but exponentially)
Kindly regards
pixxxel schubser
Copy link to clipboard
Copied
Hi pixxxel schubser,
Thanks for all the help, you've given me a great support.
Just one last (hypothetical) question before creating a new thread?
Is it possible to loop just through a defined layer group (set) in stead of all layers and using your code to run though this layer group which is than basically just one horizontal line of nine rectangles.
A-4 & B-4 | A-3 & B-4 | A-2 & B-4 | A-1 & B-4 | A & B | A+4 & B-4 | A+3 & B-4 | A+2 & B-4 | A+1 & B-4 |
Than I just repeat your cript for every line (starting from -4 to +4), first to change the A value, than the same script with a minor adjustment to change the B-values.
I know the total script would be very long in this case (108 times your script with some adjustments per line) but I think this might be a good workaround?
regards
Dennis
Copy link to clipboard
Copied
Sorry pixxxel schubser , I made a mistake above, line should be:
A-4 & B-4 | A-3 & B-4 | A-2 & B-4 | A-1 & B-4 | A & B -4 | A+1 & B-4 | A+2 & B-4 | A+3 & B-4 | A+4 & B-4 |
So your code to change the A value, and 1 value for all B-values of that line ...
Copy link to clipboard
Copied
Possible? Yes.
But at the best: begin with the left top (or the left bottom) rectangle.
Here is the way to go (not real [JS]-code)
At first check if
L is valid &
a-4 is valid &
b-4 is valid (means: all values are in the correct range)
L = value_L
a = value_a - 4
b = value_b -4
for rectangle1 to 9
set (sColor)
a++;
next rectangle
(end of first loop)
b++;
for rectangle10 to 18
set (sColor)
a++;
next rectangle
(end of second loop)
b++;
… and so on
Copy link to clipboard
Copied
Good afternoon,
It took a while but i managed to make it work as described above.
Thanks for all the help pixxxel schubser​
Regards
Copy link to clipboard
Copied
Glad to help you.