Copy link to clipboard
Copied
I have several layers in a photoshop file that I use to mockup the final image for my colleague.
I want the other person to look at my file (or exported png) and see where he should put those parts of my mockup in his external software, using top left corner coordinates of each layer.
What I want is to be able to select layers, run a script and it would generate a new folder inside my photoshop document and add text layers with XY coordinates of each selected layer on top of it, using white color for the text and balck stroke outline for folder, in which new text overlays were created.
Something like this:
Can this be done?
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = activeDocument;
var theSelected = collectSelectedLayersBounds ();
myDocument.activeLayer = myDocument.layers[myDocument.layers.length-1];
var theGroup = myDocument.layerSets.add();
for (var m = 0; m < theSelected.length; m++) {
var thisOne = theSelected[m];
createTextLayer (thisOne[3][0]+"_"+thisOne[
...
Here is a function that applies the Layer Style Stroke to the active Layer.
You should be able to figure out which settings to adapt to meet your needs.
////// make stroke //////
function applyLayerStyleStroke () {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc12 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref7 = new ActionReference();
var idPrpr = charIDToTypeID
...
Copy link to clipboard
Copied
Could you please post complete screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible instead of snippets?
Are there other Layers, if so how would the Layers that should get coordinates-Type Layers be identified?
What is the intended output?
Do you have any experience with JavaScript?
Copy link to clipboard
Copied
Hi. Thanks for answering. I do not have any JavaScript experience, but I'd probably understand what a code snippet does.
Identification of the layers for the script should be their selection. The ones that are selected should be processed by the script.
So, user selects layers.
Runs the script.
Script fetches each layer for top left coordinates.
Script generates a new top folder.
Inside that folder it generates text layers with coordinates of each originally selected layers, using the name of the original selected layer as its own and appending the text input to it. The color is white. The size of the text labels should be defined somewhere inside the script.
Scrippt adds a black stroke modifier to the top text folder.
Here's a full screenshot of what i'm trying tto achieve:
Copy link to clipboard
Copied
Copy link to clipboard
Copied
@fundorin – It would be far easier to use a script to simply rename the selected layers with the coordinates.
Then save the selected layers with the coordinates in the name.
Then if needed run another script to remove the coordinates from the selected layer names.
Copy link to clipboard
Copied
Elaborate, please. Having the layer names with coordinates isn't the goal. Having an image with every layer's position on the canvas is.
Copy link to clipboard
Copied
// 2023, use it at your own risk;
if (app.documents.length > 0) {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var myDocument = activeDocument;
var theSelected = collectSelectedLayersBounds ();
myDocument.activeLayer = myDocument.layers[myDocument.layers.length-1];
var theGroup = myDocument.layerSets.add();
for (var m = 0; m < theSelected.length; m++) {
var thisOne = theSelected[m];
createTextLayer (thisOne[3][0]+"_"+thisOne[3][1], [thisOne[4], thisOne[5]], myDocument.resolution, theGroup)
};
app.preferences.rulerUnits = originalRulerUnits;
};
////// collect bounds of selected layers //////
function collectSelectedLayersBounds () {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// get selected layers;
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if (desc.getBoolean(stringIDToTypeID("hasBackgroundLayer")) == true) {var theAdd =0}
else {var theAdd = 1};
if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
var c = desc.count;
var selectedLayers = new Array();
// run through selected layers;
for(var i=0;i<c;i++){
var theIndex = desc.getReference( i ).getIndex()+theAdd;
// get id for solid color layers;
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID("Lyr "), theIndex );
var layerDesc = executeActionGet(ref);
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
var theClippingMasked = layerDesc.getBoolean(stringIDToTypeID ("group"));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
var theXCenter = theseBounds[0]+(theseBounds[2]-theseBounds[0])/2;
var theYCenter = theseBounds[1]+(theseBounds[3]-theseBounds[1])/2;
selectedLayers.push([theName, theIndex, theIdentifier, theseBounds, theXCenter, theYCenter]);
} catch (e) {};
};
// if only one:
}else{
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
var theClippingMasked = layerDesc.getBoolean(stringIDToTypeID ("group"));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
var theXCenter = theseBounds[0]+(theseBounds[2]-theseBounds[0])/2;
var theYCenter = theseBounds[1]+(theseBounds[3]-theseBounds[1])/2;
selectedLayers = [[theName, theIndex, theIdentifier, theseBounds, theXCenter, theYCenter]]
} catch (e) {};
};
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return selectedLayers;
};
////// add text layer //////
function createTextLayer (thisText, thePoint, res, theGroup) {
var docRef = activeDocument;
var myLayerRef = theGroup.artLayers.add();
myLayerRef.kind = LayerKind.TEXT;
myLayerRef.name = thisText;
var myTextRef = myLayerRef.textItem;
myTextRef.kind = TextType.POINTTEXT;
myTextRef.size = 24 * 72 / res;
myTextRef.font = "Arial";
myTextRef.justification = Justification.CENTER;
//Set text colour in RGB values
var newColor = new SolidColor();
newColor.rgb.red = 0;
newColor.rgb.green = 0;
newColor.rgb.blue = 0;
myTextRef.color = newColor;
// set the position;
myTextRef.position = [thePoint[0], thePoint[1]];
//myTextRef.position = [thePoint[0] * 72 / res, thePoint[1] * 72 / res];
myLayerRef.blendMode = BlendMode.NORMAL;
myLayerRef.opacity = 100;
myTextRef.useAutoLeading = false;
myTextRef.leading = 0;
myTextRef.contents = thisText;
return docRef.activeLayer
};
Copy link to clipboard
Copied
Thank you very much for your response.
I'm currently trying to modify it so that it would fit my needs.
Changed the color, size and output coordinates. It was showing them for the center, while I needed the top left corner.
It looks great now!
Copy link to clipboard
Copied
Here is a function that applies the Layer Style Stroke to the active Layer.
You should be able to figure out which settings to adapt to meet your needs.
////// make stroke //////
function applyLayerStyleStroke () {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc12 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref7 = new ActionReference();
var idPrpr = charIDToTypeID( "Prpr" );
var idLefx = charIDToTypeID( "Lefx" );
ref7.putProperty( idPrpr, idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref7.putEnumerated( idLyr, idOrdn, idTrgt );
desc12.putReference( idnull, ref7 );
var idT = charIDToTypeID( "T " );
var desc13 = new ActionDescriptor();
var idScl = charIDToTypeID( "Scl " );
var idPrc = charIDToTypeID( "#Prc" );
desc13.putUnitDouble( idScl, idPrc, 100.000000 );
var idFrFX = charIDToTypeID( "FrFX" );
var desc14 = new ActionDescriptor();
var idenab = charIDToTypeID( "enab" );
desc14.putBoolean( idenab, true );
var idStyl = charIDToTypeID( "Styl" );
var idFStl = charIDToTypeID( "FStl" );
var idInsF = charIDToTypeID( "InsF" );
desc14.putEnumerated( idStyl, idFStl, idInsF );
var idPntT = charIDToTypeID( "PntT" );
var idFrFl = charIDToTypeID( "FrFl" );
var idSClr = charIDToTypeID( "SClr" );
desc14.putEnumerated( idPntT, idFrFl, idSClr );
var idMd = charIDToTypeID( "Md " );
var idBlnM = charIDToTypeID( "BlnM" );
var idNrml = charIDToTypeID( "Nrml" );
desc14.putEnumerated( idMd, idBlnM, idNrml );
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc14.putUnitDouble( idOpct, idPrc, 100.000000 );
var idSz = charIDToTypeID( "Sz " );
var idPxl = charIDToTypeID( "#Pxl" );
desc14.putUnitDouble( idSz, idPxl, 4.000000 );
var idClr = charIDToTypeID( "Clr " );
var desc15 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc15.putDouble( idRd, 0.000000 );
var idGrn = charIDToTypeID( "Grn " );
desc15.putDouble( idGrn, 0.000000 );
var idBl = charIDToTypeID( "Bl " );
desc15.putDouble( idBl, 0.000000 );
var idRGBC = charIDToTypeID( "RGBC" );
desc14.putObject( idClr, idRGBC, desc15 );
var idFrFX = charIDToTypeID( "FrFX" );
desc13.putObject( idFrFX, idFrFX, desc14 );
var idLefx = charIDToTypeID( "Lefx" );
desc12.putObject( idT, idLefx, desc13 );
executeAction( idsetd, desc12, DialogModes.NO );
};