Photoshop Scripting select contents of a layer & color - photoshop

Using a javascript script in Photoshop 2022 (v 23.0.1), I am trying to change the color of a single item in one of my layers. I can access the layer, but I cannot change the color of it's contents.
var document = activeDocument;
var groupA = document.layers["Group"];
var layerA = groupA.layers["Layer In Group"];
var layerB = groupA.layers["Clipping Mask for layerA"];
The layerA contains a single item which is colored white. I'd like to change it's color.
I assume I need to select the contents of that layer, then apply a color to it. But I'm not sure this is the best way to do this.
I could also add a clipping mask for that layer, then fill that with color. Would this be easier/better?
Ideally I'd like to change it using a hex color code, but any way I can change it would be fine.
UPDATE: I was able to solve the problem by making the layer the activeLayer in the document.
// set the active layer to the layer requiring fill color
document.activeLayer = layerB;
// getBodyFillColor() is my method that returns the correct color
var color = getBodyFillColor();
// Once I set the active layer, it's automatically the selection layer?? (not sure how this works)
document.selection.fill(color);

You could just fill with a colour:
// Fill colour
var myRGBCol = [255, 0, 128]; //define your colour here
var col = new SolidColor;
col.rgb.red = myRGBCol[0];
col.rgb.green = myRGBCol[1];
col.rgb.blue = myRGBCol[2];
var blend = ColorBlendMode.NORMAL; // Normal
var op = 100; // opacity
document.selection.fill(col, blend, op, false);

Related

Photoshop CC eye dropper tool script

I have a batch action to place a pure white background behind an image. I want to be able to select the color from a fixed pixel position on each photo. When I record the eye dropper in actions it only records the color i picked, not the action of picking the color. I have looked into scripting and tried various solutions on the web.
This is the script I have tried:
var docRef = app.activeDocument;
var pixelLoc = [32,42];
var colorSamplerRef = docRef.colorSamplers.add(pixelLoc);
app.foregroundColor = colorSamplerRef.color;
It doesn't perform the action I need though. Which is select - > color range -> eye dropper tool on fixed position
To achieve this you can create a custom function which invokes the Color Range generated selection, (named selectColorRange in the example gist below).
The selectColorRange function utilizes new ActionDescripter() to configure the properties, which are akin to the settings options shown in the dialog box when you manually choose Select -> Color Range from the Menu bar. This function is invoked after adding the colorSampler at a given x/y coordinate as follows:
selectColorRange(sampledColor, 80); // <-- Specify the fuzziness as required.
Note how we pass in the previous sampledColor value, and a fuzziness value of 80, (which is the default value used in Photoshop).
Example gist:
var docRef = app.activeDocument; // Assumes a document is active.
// Remove any Color Samplers that may already exist.
docRef.colorSamplers.removeAll();
// deselct any selection that may already exist.
docRef.selection.deselect();
// Get color sample from a given x,y coordinate.
var pixelLoc = [32,42];
var colorSampleRef = docRef.colorSamplers.add(pixelLoc);
var sampledColor = colorSampleRef.color;
// Set the foreground color to the sampled color.
app.foregroundColor = sampledColor;
/**
* Invokes and configures `Select > Color Range` from menu bar.
* #param {Object} color - The sampled color object.
* #param {Number} [fuzziness=80] - The Fuziness value (between 0-200).
*/
function selectColorRange(color, fuzziness) {
fuzziness = (typeof fuzziness !== 'undefined') ? fuzziness : 80;
var d1 = new ActionDescriptor();
// Set the amount of Fuzziness.
d1.putInteger(charIDToTypeID('Fzns'), fuzziness);
// Set invert option to false.
d1.putBoolean(charIDToTypeID('Invr'), false);
d1.putInteger(stringIDToTypeID('colorModel'), 0);
// Set the lAB value for Minimum.
var d2 = new ActionDescriptor();
d2.putDouble(charIDToTypeID('Lmnc'), color.lab.l);
d2.putDouble(charIDToTypeID('A '), color.lab.a);
d2.putDouble(charIDToTypeID('B '), color.lab.b);
d1.putObject(charIDToTypeID('Mnm '), charIDToTypeID('LbCl'), d2);
// Set the lAB value for Maximum.
var d3 = new ActionDescriptor();
d3.putDouble(charIDToTypeID('Lmnc'), color.lab.l);
d3.putDouble(charIDToTypeID('A '), color.lab.a);
d3.putDouble(charIDToTypeID('B '), color.lab.b);
d1.putObject(charIDToTypeID('Mxm '), charIDToTypeID('LbCl'), d3);
// Run the Color Range command without showing dialog.
executeAction(charIDToTypeID('ClrR'), d1, DialogModes.NO);
}
// Invoke the function passing in the sample
// color and default fuzziness value.
selectColorRange(sampledColor, 80);
//docRef.selection.clear();
//docRef.selection.fill(app.foregroundColor);
// Remove the Color Sampler.
colorSampleRef.remove();
Additional notes:
Photoshop allows a maximum of four color samplers to be added. If the document already included four color samplers then we'd get an error when attempting to add another one. To avoid the potential of this happening we invoke docRef.colorSamplers.removeAll(); to remove them all first.
Also, to ensure the resultant selection (i.e. the selection created after invoking the selectColorRange function), is not affected by any existing selection(s) we deselect them all first by invoking docRef.selection.deselect();
Finally, the color sampler that we initially added is removed by calling colorSampleRef.remove();
I'm unsure from your question what you intend to to with the selection once it's been created. As an example;
Lets say you wanted to clear the contents of the selection then you'd invoke docRef.selection.clear();.
If you wanted to fill the resultant selection with the previously sampled color then call docRef.selection.fill(app.foregroundColor);

Adobe Photoshop Scripting - How to Select Bounding Box Around Current Selection?

Does anyone know whether it's possible, in Photoshop extend script, to convert an irregular selection (e.g. magic wand tool selection) into a rectangular selection encompassing the top, left, bottom and right bounds of the selection?
Here it is, I have documented the code so you can modify it later if you need. Also, check page 166 and following of Photoshop's JS reference manual, you may read more about selections - you can set feather, extend/intersect/etc. the selection if you need to.
Made for CS6, should work with latter.
#target photoshop
if (documents.length == 0) {
alert("nothing opened");
} else {
// start
//setup
var file = app.activeDocument;
var selec = file.selection;
//run
var bnds = selec.bounds; // get the bounds of current selection
var // save the particular pixel values
xLeft = bnds[0],
yTop = bnds[1],
xRight = bnds[2],
yBottom = bnds[3];
var newRect = [ [xLeft,yTop], [xLeft,yBottom], [xRight,yBottom], [xRight,yTop] ]; // set coords for selection, counter-clockwise
selec.deselect;
selec.select(newRect);
// end
}

Add flat amount to canvas size

I want to have some automated process (either action or script) that will copy selection(assumes something has already been selected), place in new canvas, increase canvas size by exactly 10 pixels in height & width, then save it to the desktop.
I'm currently using an action and it works correctly with the exception of the 10 pixels part. I can do something like 10% by using the percentage adjustment in the canvas size menu, but I can't figure out how to do exactly 10 pixels. During the recording, if I just increase the canvas size by 10 pixels it'll record that exact amount (say it was 100x100, it records that I resized canvas to 110x100). So when I play that action on a selection that's of size 50x50 it resizes it to 110x110.... So the problem is that the action records the literal value of the canvas resize and not the add 10 pixels part...
Any ideas here?
This can be scripted as well, but if you've already got an action set up, try modifying your action to do the following:
paste the selection into new document larger than you expect to ever require
expand the selection by 10 px
crop the document to the selection
save
Or, to script it you can tweak the following sample. It assumes you have already copied your image to the clipboard:
#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
var doc = app.documents.add('1000px');
var lyr = doc.artLayers.add();
doc.activeLayer = lyr;
doc.paste ();
var bnds = lyr.bounds;
var unitsToAdd = new UnitValue(10, 'px');
bnds[0] = bnds[0] - unitsToAdd;
bnds[1] = bnds[1] - unitsToAdd;
bnds[2] = bnds[2] + unitsToAdd;
bnds[3] = bnds[3] + unitsToAdd;
doc.crop(bnds) ;
doc.saveAs(new File('/c/temp/temp.psd'));

How to change the size and color of Petrel "Attributes Labels" using Ocean

I add a property to a PolylineSet using the code below (In the Petrel UI they are named “Attribute labels”)
using (ITransaction trans = DataManager.NewTransaction())
{
trans.Lock(polylineSet);
PolylinePropertyCollection ppc = polylineSet.CreatePropertyCollection();
trans.Lock(ppc);
property = ppc.CreateProperty(PetrelProject.WellKnownTemplates.MiscellaneousGroup.General, name);
trans.Commit();
}
I would like to change the size and color.
Does anyone know if this is possible via Ocean?
I want to do this because these labels have a size of 1 and color black and it isn't a good default for me.
Thanks in advance
I haven't specifically altered the color and size of labels, but have dealt with size and color for polylinesets. Maybe you can use the INumberAnnotation style object? It seems to have properties for setting font color and size.
Slb.Ocean.Petrel.UI.Style.IStyleFactory factory = CoreSystem.GetService<Slb.Ocean.Petrel.UI.Style.IStyleFactory>(ppc);
Slb.Ocean.Petrel.UI.Style.INumberAnnotation style = (Slb.Ocean.Petrel.UI.Style.INumberAnnotation)factory.GetStyle(ppc, myWindow);
if (style != null)
{
style.FontColorType = Slb.Ocean.Petrel.UI.Style.ColorType.White;
style.FontSize = 400;
}
Hope that works.

iTextSharp Overlay Image

Hi guys I have an instance where I have a logo image as part of some artwork..
If a user uploads a new logo I have a form field which is larger than the default logo.
I then use that form field to position the new image.
The problem is I need to set the background colour of that form field to white so that it covers the old logo in the event that the new image is smaller than the old logo..
what I have done is:
foreach (var imageField in imageReplacements)
{
fields.SetFieldProperty(imageField.Key, "bgcolor", iTextSharp.text.Color.WHITE, null);
fields.RegenerateField(imageField.Key);
PdfContentByte overContent = stamper.GetOverContent(imageField.Value.PageNumber);
float[] logoArea = fields.GetFieldPositions(imageField.Key);
if (logoArea != null)
{
iTextSharp.text.Rectangle logoRect = new iTextSharp.text.Rectangle(logoArea[1], logoArea[2], logoArea[3], logoArea[4]);
var logo = iTextSharp.text.Image.GetInstance(imageField.Value.Location);
if (logo.Width >= logoRect.Width || logo.Height >= logoRect.Height)
{
logo.ScaleToFit(logoRect.Width, logoRect.Height);
}
logo.Alignment = iTextSharp.text.Image.ALIGN_LEFT;
logo.SetAbsolutePosition(logoRect.Left, logoArea[2] + (logoRect.Height - logo.ScaledHeight) / 2);
// left: logoArea[3] - logo.ScaledWidth + (logoRect.Width - logo.ScaledWidth) / 2
overContent.AddImage(logo);
}
}
The problem with this is that the background colour of the field is set to white and the image then doesn't appear.. i remove the SetFieldProperty and RegenerateField commands and the image replacement works fine..
is there a way to set a stacking order on layers?
Annotations (such as form fields) are always on top of page contents. Annotation Z order is just the order of the annotations array on a given page.
Page content Z order is just the order everything appears in the content stream. New drawing operators go on top of proceeding operators.
If you want to cover your old image, draw a white box over it and then draw the new logo over top that. No need to worry about annotations.
Actually, all you really need to do is not set the background color of the imageField. You're already scaling the new logo to match the size of the old one.
However, if you really must draw that white box, it's fairly simple:
overContent.setColorFill(iTextSharp.text.Color.WHITE);
overContent.rectangle( logoRect );
overcontent.fill();