Copy link to clipboard
Copied
Hi,
I have some code which swap layer in exact position but not in size,
// swapPosition-mirror.jsx - Adobe Photoshop Script
// Version: 0.2.1
// Author: Anton Lyubushkin (nvkz.nemo@gmail.com)
// Website: http://lyubushkin.pro/
// ============================================================================
// Installation:
// 1. Place script in:
// PC(32): C:\Program Files (x86)\Adobe\Adobe Photoshop CC#\Presets\Scripts\
// PC(64): C:\Program Files\Adobe\Adobe Photoshop CC# (64 Bit)\Presets\Scripts\
// Mac: <hard drive>/Applications/Adobe Photoshop CC#/Presets/Scripts/
// 2. Restart Photoshop
// 3. Choose File > Scripts > swapPosition-mirror
// ============================================================================
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
if (selectedLayers.length == 2) {
try {
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (app.activeDocument.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var xleft = activeDocument.activeLayer.bounds[0]
var xright = activeDocument.activeLayer.bounds[2]
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
app.activeDocument.activeHistoryState = app.activeDocument.historyStates[app.activeDocument.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xleft = activeDocument.activeLayer.bounds[0]
var xright = activeDocument.activeLayer.bounds[2]
}
sLayers.push([activeDocument.activeLayer, xpos, ytop, ybot, height, xleft, xright]);
}
var delta0_y = 0;
var delta1_y = 0;
function differentHeight() {
if (sLayers[1][4] != sLayers[0][4]) {
return true
} else {
return false
}
}
function returnSmaller() {
if (sLayers[1][4] < sLayers[0][4]) {
return [sLayers[1][0], sLayers[0][0]]
} else {
return [sLayers[0][0], sLayers[1][0]]
}
}
if (sLayers[1][2] != sLayers[0][2]) {
if (differentHeight() == true) {
var smallLyr = returnSmaller();
if (smallLyr[0].bounds[1] < smallLyr[1].bounds[1] || smallLyr[0].bounds[3] > smallLyr[1].bounds[3]) {
delta0_y = (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2]))) - (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2])));
delta1_y = (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2]))) - (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2])));
} else {
delta0_y = 0;
delta1_y = 0;
}
} else {
delta0_y = (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2]))) - (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2])));
delta1_y = (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2]))) - (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2])));
}
}
if (sLayers[0][5] < sLayers[1][5] && sLayers[0][6] < sLayers[1][6]) {
var delta0_x = sLayers[1][6] - sLayers[0][6];
var delta1_x = sLayers[0][5] - sLayers[1][5];
} else {
var delta0_x = sLayers[1][5] - sLayers[0][5];
var delta1_x = sLayers[0][6] - sLayers[1][6];
}
sLayers[0][0].translate(delta0_x, delta0_y);
sLayers[1][0].translate(delta1_x, delta1_y);
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
} catch (e) {
alert("Oops! These layers cannot be repositioned");
}
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
What i want is swap layer position and same size, like this:
Can anyone help with this?
Thank you.
You can try this. It will only resize base on width.
...// swapPosition-mirror.jsx - Adobe Photoshop Script
// Version: 0.2.1
// Author: Anton Lyubushkin (nvkz.nemo@gmail.com)
// Website: http://lyubushkin.pro/
// ============================================================================
// Installation:
// 1. Place script in:
// PC(32): C:\Program Files (x86)\Adobe\Adobe Photoshop CC#\Presets\Scripts\
// PC(64): C:\Program Files\Adobe\Adobe Phot
Copy link to clipboard
Copied
The two layer you show have 1:1 aspect ratio so what you want to do may be easy to do. However, If the two layers do not have the same aspect ratio you have a big problem. Do you want to distort or crop the layers which aspect ratios do you want the resize layer to have. What kind of layer do you want to be able to process? For example smart object layer have associated transforn that size, position and can distort the layer. They may be particularly hard to handle.,
Copy link to clipboard
Copied
What I want is of course all kind of layers ,
but if it can't be all kind of layers,
what kinds of layers can be used to suit the purpose I want?
then what should be added to the above script?
Thanks JJMack
Copy link to clipboard
Copied
Just get the sizes of both layers, the calculate the ratio to size in each direction (one layer size to the other and the other to the first), then add a resize line of code for each layer.
Copy link to clipboard
Copied
Hi Chuck Uebele
Thank you for the answer, but I don't understand how to write in JavaScript, can you help me write the javascript, thank you very much
Copy link to clipboard
Copied
Hi Chuck Uebele
Thank you for the answer, but I don't understand how to write in JavaScript, can you help me write the javascript, thank you very much
Copy link to clipboard
Copied
IMO you would introduce to much distortion with image layers solid color layers will work ok. Only if the layers have the same aspect ratio will the resizing not distort. Like your example where both layer have a 1:1 aspect ratio.
It is not hard to script all you are writing is you want to move two layers and change these layer sizes. That is easy to do using the two layers bounds. You are moving the layers center point to the other layer's center point and changing the layer width and height to the other layer's width and height. That is just two transform you are doing. However, layers like shape, text, image, smart object etc all will distort if the two layer do not have the same aspect ratio. The layer's width and height will be changed by a different percentage. The layers content will distort.
In the example above both image are 8.2MP 16bit color smart object layers from ACR one has a Landscape 3:2 aspect ratio the other a portrait 2:3 aspect ratio after the two transform both still have 8.2MP but the portrait has been distorted into a 3:2 Landscape aspect ratio and the landscape into a 2:3 portrait aspect ratio.
Copy link to clipboard
Copied
of course i will not do for photo that have different ratio that will make distortion,
Copy link to clipboard
Copied
Text layers and shape layer will also distort if the two layers have different aspect ratios even though vector graphics will be used during the resize.
Here is I ran his script
Copy link to clipboard
Copied
You can try this. It will only resize base on width.
// swapPosition-mirror.jsx - Adobe Photoshop Script
// Version: 0.2.1
// Author: Anton Lyubushkin (nvkz.nemo@gmail.com)
// Website: http://lyubushkin.pro/
// ============================================================================
// Installation:
// 1. Place script in:
// PC(32): C:\Program Files (x86)\Adobe\Adobe Photoshop CC#\Presets\Scripts\
// PC(64): C:\Program Files\Adobe\Adobe Photoshop CC# (64 Bit)\Presets\Scripts\
// Mac: <hard drive>/Applications/Adobe Photoshop CC#/Presets/Scripts/
// 2. Restart Photoshop
// 3. Choose File > Scripts > swapPosition-mirror
// ============================================================================
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
if (selectedLayers.length == 2) {
try {
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (app.activeDocument.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var xleft = activeDocument.activeLayer.bounds[0]
var xright = activeDocument.activeLayer.bounds[2]
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
app.activeDocument.activeHistoryState = app.activeDocument.historyStates[app.activeDocument.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xleft = activeDocument.activeLayer.bounds[0]
var xright = activeDocument.activeLayer.bounds[2]
}
sLayers.push([activeDocument.activeLayer, xpos, ytop, ybot, height, xleft, xright]);
}
var delta0_y = 0;
var delta1_y = 0;
function differentHeight() {
if (sLayers[1][4] != sLayers[0][4]) {
return true
} else {
return false
}
}
function returnSmaller() {
if (sLayers[1][4] < sLayers[0][4]) {
return [sLayers[1][0], sLayers[0][0]]
} else {
return [sLayers[0][0], sLayers[1][0]]
}
}
if (sLayers[1][2] != sLayers[0][2]) {
if (differentHeight() == true) {
var smallLyr = returnSmaller();
if (smallLyr[0].bounds[1] < smallLyr[1].bounds[1] || smallLyr[0].bounds[3] > smallLyr[1].bounds[3]) {
delta0_y = (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2]))) - (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2])));
delta1_y = (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2]))) - (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2])));
} else {
delta0_y = 0;
delta1_y = 0;
}
} else {
delta0_y = (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2]))) - (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2])));
delta1_y = (sLayers[0][3] - ((sLayers[0][3] - sLayers[0][2]))) - (sLayers[1][3] - ((sLayers[1][3] - sLayers[1][2])));
}
}
if (sLayers[0][5] < sLayers[1][5] && sLayers[0][6] < sLayers[1][6]) {
var delta0_x = sLayers[1][6] - sLayers[0][6];
var delta1_x = sLayers[0][5] - sLayers[1][5];
} else {
var delta0_x = sLayers[1][5] - sLayers[0][5];
var delta1_x = sLayers[0][6] - sLayers[1][6];
}
sLayers[0][0].translate(delta0_x, delta0_y);
sLayers[1][0].translate(delta1_x, delta1_y);
///////////////////////////////////////////////////////
var width1 = sLayers[0][0].bounds[2] - sLayers[0][0].bounds[0];
var width2 = sLayers[1][0].bounds[2] - sLayers[1][0].bounds[0];
var ratio1 = width1/width2;
var ratio2 = width2/width1;
var layer1= doc.activeLayer = sLayers[0][0]
layer1.resize (100*ratio2, 100* ratio2)
var layer2= doc.activeLayer = sLayers[1][0]
layer2.resize (100*ratio1, 100* ratio1)
///////////////////////////////////////////////////////
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
} catch (e) {
alert("Oops! These layers cannot be repositioned");
}
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
Copy link to clipboard
Copied
Thank you, it works perfectly.......
Copy link to clipboard
Copied
Hello, Chuck Uebele
Can you please help me again, the previous script is only for 2 layers,
What about some layers, I take for example 6 layers,
every time I run the script it will change randomly swap the layer, and if I repeat the script it will change randomly again
please see the example below:
and this is not limited to a number of layers, it is possible for me to select 100 layers, and the script will swap randomly,
can this be done?
if you can help me make the script
Thank you very much...........
Copy link to clipboard
Copied
The script that he posted requires two layer to be targeted no more no less. Those two layers are moved and they are resized based on layer width he stated. The layer sizes are not swapped. The script does two layer moves and the script does two layer resizes.
It would be very easy to modify that script to do the two Layer Transform you wanted to swap the layers location and sized. Both scripts will distort layers. However If the Layer have the same aspect ratio the script that does the two layer Transform will swap the two layer location and sizes without distorting the layers. Because the width and heights of the last will be resized by the same percentage.
I believe I may have modified the script to do the two required Layer transforms.
// swap two layers Position and sizes
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
if (selectedLayers.length == 2) {
try {
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (app.activeDocument.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
var xleft = activeDocument.activeLayer.bounds[0]
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2
var ycenter = activeDocument.activeLayer.bounds[1] + height/2
var xright = activeDocument.activeLayer.bounds[2]
app.activeDocument.activeHistoryState = app.activeDocument.historyStates[app.activeDocument.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2
var ycenter = activeDocument.activeLayer.bounds[1] + height/2
var xleft = activeDocument.activeLayer.bounds[0]
var xright = activeDocument.activeLayer.bounds[2]
}
sLayers.push([activeDocument.activeLayer, xleft, ytop, width, height, xcenter, ycenter, xright, ybot]);
}
var oneWidth = sLayers[0][3]
var oneHeight = sLayers[0][4]
var oneXcenter = sLayers[0][5]
var oneYcenter = sLayers[0][6]
var twoWidth = sLayers[1][3]
var twoHeight = sLayers[1][4]
var twoXcenter = sLayers[1][5]
var twoYcenter = sLayers[1][6]
var layer1= doc.activeLayer = sLayers[0][0]
if (oneXcenter<=twoXcenter) Xdelta = twoXcenter-oneXcenter;
else Xdelta = -twoXcenter+oneXcenter;
if (oneYcenter<=twoYcenter) Ydelta = twoYcenter-oneYcenter;
else Ydelta = -twoYcenter+oneYcenter;
if (oneWidth<=twoWidth) percentWidth = twoWidth/oneWidth*100;
else percentWidth = oneWidth/twoWidth*100;
if (oneHeight<=twoHeight) percentHeight = oneHeight/twoHeight*100;
else percentHeight = twoHeight/oneHeight*100;
transform(Xdelta, Ydelta, percentWidth, percentHeight);
var layer2= doc.activeLayer = sLayers[1][0]
if (twoXcenter<=oneXcenter) Xdelta = twoXcenter-oneXcenter;
else Xdelta = -twoXcenter+oneXcenter;
if (twoYcenter<=oneYcenter) Ydelta = twoYcenter-oneYcenter;
else Ydelta = -twoYcenter+oneYcenter;
if (twoWidth<=oneWidth) percentWidth = twoWidth/oneWidth*100;
else percentWidth = oneWidth/twoWidth*100;
if (twoHeight<=oneHeight) percentHeight = oneHeight/twoHeight*100;
else percentHeight = twoHeight/oneHeight*100;
transform(Xdelta, Ydelta, percentWidth, percentHeight);
///////////////////////////////////////////////////////
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
} catch (e) {
alert(e + ': on line ' + e.line, 'Script Error', true);
}
}
function transform(DeltaX, DeltaY, WidthPercent, HeightPercent) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor.putEnumerated( stringIDToTypeID( "freeTransformCenterState" ), stringIDToTypeID( "quadCenterState" ), stringIDToTypeID( "QCSAverage" ));
descriptor2.putUnitDouble( stringIDToTypeID( "horizontal" ), stringIDToTypeID( "pixelsUnit" ), DeltaX );
descriptor2.putUnitDouble( stringIDToTypeID( "vertical" ), stringIDToTypeID( "pixelsUnit" ), DeltaY );
descriptor.putObject( stringIDToTypeID( "offset" ), stringIDToTypeID( "offset" ), descriptor2 );
descriptor.putUnitDouble( stringIDToTypeID( "width" ), stringIDToTypeID( "percentUnit" ), WidthPercent );
descriptor.putUnitDouble( stringIDToTypeID( "height" ), stringIDToTypeID( "percentUnit" ), HeightPercent );
]executeAction( stringIDToTypeID( "transform" ), descriptor, DialogModes.NO );
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
Copy link to clipboard
Copied
If I run the script twice it works the first time the second time is do it position layers off canvas so my delta position logic needs to be fixed. I'll fix it some time I have to go away now. Fix the positioning bug but not I have resizing problem. I'll have to look at the problem been a long time since High school math. Wish I could type...
// swap two layers Position and sizes
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
if (selectedLayers.length == 2) {
try {
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (app.activeDocument.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
var xleft = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2;
var ycenter = activeDocument.activeLayer.bounds[1] + height/2;
var xright = activeDocument.activeLayer.bounds[2]
app.activeDocument.activeHistoryState = app.activeDocument.historyStates[app.activeDocument.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2;
var ycenter = activeDocument.activeLayer.bounds[1] + height/2;
var xleft = activeDocument.activeLayer.bounds[0];
var xright = activeDocument.activeLayer.bounds[2];
}
sLayers.push([activeDocument.activeLayer, xleft, ytop, width, height, xcenter, ycenter, xright, ybot]);
}
var oneWidth = sLayers[0][3]
var oneHeight = sLayers[0][4]
var oneXcenter = sLayers[0][5]
var oneYcenter = sLayers[0][6]
var twoWidth = sLayers[1][3]
var twoHeight = sLayers[1][4]
var twoXcenter = sLayers[1][5]
var twoYcenter = sLayers[1][6]
var layer1= doc.activeLayer = sLayers[0][0]
if (oneXcenter<=twoXcenter) Xdelta = twoXcenter-oneXcenter;
else Xdelta = -(oneXcenter-twoXcenter);
if (oneYcenter<=twoYcenter) Ydelta = twoYcenter-oneYcenter;
else Ydelta = -twoYcenter+oneYcenter;
if (oneWidth<=twoWidth) percentWidth = twoWidth/oneWidth*100;
else percentWidth = oneWidth/twoWidth*100;
if (oneHeight<=twoHeight) percentHeight = oneHeight/twoHeight*100;
else percentHeight = twoHeight/oneHeight*100;
transform(Xdelta, Ydelta, percentWidth, percentHeight);
var layer2= doc.activeLayer = sLayers[1][0]
if (twoXcenter<=oneXcenter) Xdelta = -(twoXcenter-oneXcenter);
else Xdelta = -twoXcenter+oneXcenter;
if (twoYcenter<=oneYcenter) Ydelta = twoYcenter-oneYcenter;
else Ydelta = -twoYcenter+oneYcenter;
if (twoWidth<=oneWidth) percentWidth = twoWidth/oneWidth*100;
else percentWidth = oneWidth/twoWidth*100;
if (twoHeight<=oneHeight) percentHeight = oneHeight/twoHeight*100;
else percentHeight = twoHeight/oneHeight*100;
transform(Xdelta, Ydelta, percentWidth, percentHeight);
///////////////////////////////////////////////////////
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
} catch (e) {
alert(e + ': on line ' + e.line, 'Script Error', true);
}
}
function transform(DeltaX, DeltaY, WidthPercent, HeightPercent) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor.putEnumerated( stringIDToTypeID( "freeTransformCenterState" ), stringIDToTypeID( "quadCenterState" ), stringIDToTypeID( "QCSAverage" ));
descriptor2.putUnitDouble( stringIDToTypeID( "horizontal" ), stringIDToTypeID( "pixelsUnit" ), DeltaX );
descriptor2.putUnitDouble( stringIDToTypeID( "vertical" ), stringIDToTypeID( "pixelsUnit" ), DeltaY );
descriptor.putObject( stringIDToTypeID( "offset" ), stringIDToTypeID( "offset" ), descriptor2 );
descriptor.putUnitDouble( stringIDToTypeID( "width" ), stringIDToTypeID( "percentUnit" ), WidthPercent );
descriptor.putUnitDouble( stringIDToTypeID( "height" ), stringIDToTypeID( "percentUnit" ), HeightPercent );
executeAction( stringIDToTypeID( "transform" ), descriptor, DialogModes.NO );
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
Copy link to clipboard
Copied
It can be done, but it would be a lot of work to get the logistics right.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Chuck stated "It can be done, but it would be a lot of work to get the logistics right."
How much experience do you have Scripting Photoshop using JavaScript, DOM and Action manager code?
You are asking Chuck to do a lot of work for you. You would need to design the Process you want programmed and come up with some randomizing process. How much experience do you have designing Photoshop automation processes.
Where do you need help. What have you coded so far?
Copy link to clipboard
Copied
Chuck Uebele
A very interesting script
when I use it I have a problem the images exchanged move to the left or right
how to avoid this problem.
before
after
Copy link to clipboard
Copied
geppettol66959005 escreveu
Chuck Uebele
A very interesting script
when I use it I have a problem the images exchanged move to the left or right
how to avoid this problem.
before
after
I also noticed this same problem, always moving to the right or left.
Copy link to clipboard
Copied
The reason, the layers are off set is that the original script moved and positioned the layers by their edge, not the center of the layers. So when the layers are resized, they don't line up right. Only way to fix that would be to change the original scripts translate to use the center of the layers. Here is a script that should randomly move and size multiple layers:
#target photoshop
var doc = activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
var xPos, yPos, wid
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (doc.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
xPos = (doc.activeLayer.bounds[0] +doc.activeLayer.bounds[2])/2;
yPos = (doc.activeLayer.bounds[1] +doc.activeLayer.bounds[3])/2;
wid = doc.activeLayer.bounds[2] - doc.activeLayer.bounds[0];
doc.activeHistoryState = doc.historyStates[doc.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
xPos = (doc.activeLayer.bounds[0] +doc.activeLayer.bounds[2])/2;
yPos = (doc.activeLayer.bounds[1] +doc.activeLayer.bounds[3])/2;
wid = doc.activeLayer.bounds[2] - doc.activeLayer.bounds[0];
}
sLayers.push([doc.activeLayer, xPos, yPos, wid]);
}
//================
var aCopy = sLayers.slice();
var aRan = new Array();
var len = sLayers.length;
for(var i=0;i<len;i++){
var num = Math.floor(Math.random()*aCopy.length)
aRan.push(aCopy[num])
aCopy.splice(num,1)
}
for(var i=0;i<len;i++){moveLayer (aRan[0], sLayers[1], aRan[1], sLayers[2], aRan[2], sLayers[3], aRan[3])}
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
function moveLayer(lay,xPos1,xPos2,yPos1,yPos2,wid1,wid2){
doc.activeLayer = lay;
var ratio = (wid1/wid2)*100;
var deltaX = xPos1-xPos2;
var deltaY = yPos1-yPos2;
lay.translate(deltaX,deltaY);
lay.resize(ratio,ratio);
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Your original request was and you want to support many layer types
I was worried about the size aspect of you request. I did some more thinking about Size. If you think about layer size. A layer has a rectangular bounds. the rectangle has a width and a height the Width Pixels time Height = number of possible pixel the layer can have. For the layer can be ant shape that rectangle area even text. So if you resize based one the total number of pixels you can retain the layers aspect ratio and the image within the area will change in size but will not. So I fixed the positioning Problem I had in my script based on Chuck's first script and change the resize to be done for the number of pixels a layer can have. If the two layers are different in size their layers will be resize for number of possible pixels and the layer content will not distort. Text will change size as will images however the layers content will not distort. The resize will be a constrained resize. So here you go.
// swap two layers Position and resizes JJMack
#target photoshop
app.bringToFront();
var doc = app.activeDocument;
var selectedLayers = getSelectedLayersIndex(doc);
if (selectedLayers.length == 2) {
app.activeDocument.selection.deselect();
var orig_ruler_units = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS; // Set the ruler units to PIXELS
try {
for (var i = 0; selectedLayers.length > i; i++) {
var sLayers = new Array();
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, false);
if (app.activeDocument.activeLayer.typename == "LayerSet") {
executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
var xleft = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2;
var ycenter = activeDocument.activeLayer.bounds[1] + height/2;
var xright = activeDocument.activeLayer.bounds[2]
app.activeDocument.activeHistoryState = app.activeDocument.historyStates[app.activeDocument.historyStates.length - 2];
selectLayerByIndex(selectedLayers, false);
} else {
var xpos = activeDocument.activeLayer.bounds[0];
var ytop = activeDocument.activeLayer.bounds[1];
var ybot = activeDocument.activeLayer.bounds[3];
var width = activeDocument.activeLayer.bounds[2] - activeDocument.activeLayer.bounds[0];
var height = activeDocument.activeLayer.bounds[3] - activeDocument.activeLayer.bounds[1];
var xcenter = activeDocument.activeLayer.bounds[0] + width/2;
var ycenter = activeDocument.activeLayer.bounds[1] + height/2;
var xleft = activeDocument.activeLayer.bounds[0];
var xright = activeDocument.activeLayer.bounds[2];
}
sLayers.push([activeDocument.activeLayer, xleft, ytop, width, height, xcenter, ycenter, xright, ybot]);
}
var oneWidth = sLayers[0][3]
var oneHeight = sLayers[0][4]
var oneXcenter = sLayers[0][5]
var oneYcenter = sLayers[0][6]
var twoWidth = sLayers[1][3]
var twoHeight = sLayers[1][4]
var twoXcenter = sLayers[1][5]
var twoYcenter = sLayers[1][6]
var layer1= doc.activeLayer = sLayers[0][0]
if (oneXcenter<=twoXcenter) Xdelta = twoXcenter-oneXcenter;
else Xdelta = -(oneXcenter-twoXcenter);
if (oneYcenter<=twoYcenter) Ydelta = -(oneYcenter-twoYcenter);
else Ydelta = -(oneYcenter-twoYcenter);
ResizePercent = whatSize(twoWidth*twoHeight,oneWidth,oneHeight);
//alert(ResizePercent);
transform(Xdelta, Ydelta, ResizePercent, ResizePercent,);
var layer2= doc.activeLayer = sLayers[1][0]
if (twoXcenter<=oneXcenter) Xdelta = -(twoXcenter-oneXcenter);
else Xdelta = oneXcenter-twoXcenter;
if (twoYcenter<=oneYcenter) Ydelta = oneYcenter-twoYcenter;
else Ydelta = oneYcenter-twoYcenter;
ResizePercent = whatSize(oneWidth*oneHeight,twoWidth,twoHeight);
//alert(ResizePercent);
transform(Xdelta, Ydelta, ResizePercent, ResizePercent,);
///////////////////////////////////////////////////////
for (var i = 0, l = selectedLayers.length; i < l; i++) {
selectLayerByIndex(selectedLayers, true);
}
}
}
catch (e) {
alert(e + ': on line ' + e.line, 'Script Error', true);
}
app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings
}
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}
function whatSize(number,CurWidth,CurHeight) {
var resizePercent=(Math.sqrt(number/(CurHeight.value/CurWidth.value)))/CurWidth.value*100;
return resizePercent
}
function transform(DeltaX, DeltaY, WidthPercent, HeightPercent) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor.putEnumerated( stringIDToTypeID( "freeTransformCenterState" ), stringIDToTypeID( "quadCenterState" ), stringIDToTypeID( "QCSAverage" ));
descriptor2.putUnitDouble( stringIDToTypeID( "horizontal" ), stringIDToTypeID( "pixelsUnit" ), DeltaX );
descriptor2.putUnitDouble( stringIDToTypeID( "vertical" ), stringIDToTypeID( "pixelsUnit" ), DeltaY );
descriptor.putObject( stringIDToTypeID( "offset" ), stringIDToTypeID( "offset" ), descriptor2 );
descriptor.putUnitDouble( stringIDToTypeID( "width" ), stringIDToTypeID( "percentUnit" ), WidthPercent );
descriptor.putUnitDouble( stringIDToTypeID( "height" ), stringIDToTypeID( "percentUnit" ), HeightPercent );
executeAction( stringIDToTypeID( "transform" ), descriptor, DialogModes.NO );
}
function getSelectedLayersIndex(doc) {
var selectedLayers = [];
var ref = new ActionReference();
ref.putEnumerated(cTID('Dcmn'), cTID('Ordn'), cTID('Trgt'));
var desc = executeActionGet(ref);
if (desc.hasKey(sTID('targetLayers'))) {
desc = desc.getList(sTID('targetLayers'));
var c = desc.count;
for (var i = 0; i < c; i++) {
try {
doc.backgroundLayer;
selectedLayers.push(desc.getReference(i).getIndex());
} catch (e) {
selectedLayers.push(desc.getReference(i).getIndex() + 1);
}
}
} else {
var ref = new ActionReference();
ref.putProperty(cTID('Prpr'), cTID('ItmI'));
ref.putEnumerated(cTID('Lyr '), cTID('Ordn'), cTID('Trgt'));
try {
doc.backgroundLayer;
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')) - 1);
} catch (e) {
selectedLayers.push(executeActionGet(ref).getInteger(cTID('ItmI')));
}
}
return selectedLayers;
}
function selectLayerByIndex(index, add) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(charIDToTypeID("null"), ref);
if (add) desc.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
desc.putBoolean(charIDToTypeID("MkVs"), false);
try {
executeAction(charIDToTypeID("slct"), desc, DialogModes.NO);
} catch (e) {}
}
function cTID(s) {return app.charIDToTypeID(s);}
function sTID(s) {return app.stringIDToTypeID(s);}
Copy link to clipboard
Copied
Nice, JJ. A lot of times, I'll use the diagonal to calculate sizes. This comes in handy for scaling logos to fit either vertical or horizontal images.
Copy link to clipboard
Copied
You could put a warning that 2 levels must be selected to work.
Copy link to clipboard
Copied
It would not be a warning the script could state that two layers are required for operation. change line 12 from
if (selectedLayers.length == 2) {
}
to
if (selectedLayers.length != 2) alert("Target the two layers you want swap positions"");
else {
}
The script will fail if you target a Background layer as one of the two layers for they do not support transparency. Convert the background to a normal or smart object layer first.