Copy link to clipboard
Copied
Hello everyone,
I have 2 layers. They are both rectangles. I changed the angle of the right layer using free transform and i want to match it for the left one.
If I recorded an action in the first place it would probably work and I would have used it.
But since I didn't recorded a macro, I want to know if i can do it now using a script.
Note: Edit > Transform > Again doesn't work.
Thanks.
It is assumed that the smartobject "Layer 2" has a straight-angle border shape and has no rotations or distortions.
After you transform the "Layer 1" smartobject, run the script.
The layer "Layer 2" will take the form of a layer "Layer 1".
...var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObjectMore"));
r.putName(stringIDToTypeID("layer"), "Layer 1");
var list1 = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")).getList(stringIDToTy
Copy link to clipboard
Copied
It is assumed that there are two similar layers.
During the script, you transform the first layer, after which the transformation is applied to the second layer.
Try
var layer0 = activeDocument.layers[0];
var layer1 = activeDocument.layers[1];
app.activeDocument.suspendHistory("Transform two layers", "transform_two()");
///////////////////////////////////////////////////////////////////////////////////////////
function transform_two()
{
try {
app.preferences.rulerUnits = Units.CM;
app.activeDocument.activeLayer = layer0;
var x0 = layer0.bounds[0].value;
var y0 = layer0.bounds[1].value;
runMenuItem(stringIDToTypeID("freeTransform"));
app.activeDocument.activeLayer = layer1;
transform_again(x0, y0);
}
catch (e) { alert(e); }
}
///////////////////////////////////////////////////////////////////////////////////////////
function transform_again(x0, y0)
{
try {
var layer = app.activeDocument.activeLayer;
var x1 = layer.bounds[0].value;
var y1 = layer.bounds[1].value;
move(layer, x0-x1, y0-y1)
var r = new ActionReference();
var d = new ActionDescriptor();
r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
d.putReference( charIDToTypeID( "null" ), r );
d.putBoolean( charIDToTypeID( "LstT" ), true );
executeAction( charIDToTypeID( "Trnf" ), d, DialogModes.NO );
move(layer, x1-x0, y1-y0);
return true;
}
catch (e) { alert(e); return false; }
}
///////////////////////////////////////////////////////////////////////////////////////////
function move(layer, x, y)
{
try {
if (layer != undefined) app.activeDocument.activeLayer = layer;
var d1 = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
d1.putReference( charIDToTypeID( "null" ), ref );
var d2 = new ActionDescriptor();
d2.putUnitDouble( charIDToTypeID( "Hrzn" ), charIDToTypeID( "#Rlt" ), x*72/2.54 );
d2.putUnitDouble( charIDToTypeID( "Vrtc" ), charIDToTypeID( "#Rlt" ), y*72/2.54 );
d1.putObject( charIDToTypeID( "T " ), charIDToTypeID( "Ofst" ), d2);
executeAction( charIDToTypeID( "move" ), d1, DialogModes.NO );
}
catch (e) { alert(e); throw(e); }
}
Copy link to clipboard
Copied
sorry for the delay, this is the message i keep getting:
Copy link to clipboard
Copied
For me script worked. I created document, unlocked background, duplicated new layer and ran script.
Copy link to clipboard
Copied
Have you fulfilled the condition?
"It is assumed that there are two similar layers."
They should be at the top among all layers in the layer palette. See the script code carefully, and do not stupidly run the script.
Copy link to clipboard
Copied
i did look at the script, even renamed the layers.
Like my picture in the original post there are two layers that are not 100% the same but they have same dimensions.
if I had the exact two layers i wouldn't need a script or an action i would just duplicate it.
Copy link to clipboard
Copied
Sorry. did not notice that you have smart objects. Try this.
var layer0 = activeDocument.layers[0];
var layer1 = activeDocument.layers[1];
app.activeDocument.suspendHistory("Transform two layers", "transform_two()");
///////////////////////////////////////////////////////////////////////////////////////////
function transform_two()
{
try {
app.preferences.rulerUnits = Units.CM;
app.activeDocument.activeLayer = layer0;
var x0 = layer0.bounds[0].value;
var y0 = layer0.bounds[1].value;
transform();
app.activeDocument.activeLayer = layer1;
transform_again(x0, y0);
}
catch (e) { alert(e); }
}
///////////////////////////////////////////////////////////////////////////////////////////
function transform_again(x0, y0)
{
try {
var layer = app.activeDocument.activeLayer;
var x1 = layer.bounds[0].value;
var y1 = layer.bounds[1].value;
move(x0-x1, y0-y1)
var r = new ActionReference();
var d = new ActionDescriptor();
r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
d.putReference( charIDToTypeID( "null" ), r );
d.putBoolean( charIDToTypeID( "LstT" ), true );
executeAction( charIDToTypeID( "Trnf" ), d, DialogModes.NO );
move(x1-x0, y1-y0);
return true;
}
catch (e) { alert(e); return false; }
}
///////////////////////////////////////////////////////////////////////////////////////////
function move(x, y)
{
try {
var d1 = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
d1.putReference( charIDToTypeID( "null" ), ref );
var d2 = new ActionDescriptor();
d2.putUnitDouble( charIDToTypeID( "Hrzn" ), charIDToTypeID( "#Rlt" ), x*72/2.54 );
d2.putUnitDouble( charIDToTypeID( "Vrtc" ), charIDToTypeID( "#Rlt" ), y*72/2.54 );
d1.putObject( charIDToTypeID( "T " ), charIDToTypeID( "Ofst" ), d2);
executeAction( charIDToTypeID( "move" ), d1, DialogModes.NO );
}
catch (e) { alert(e); throw(e); }
}
////////////////////////////////////////////////////////////////////////////////////////////
function transform()
{
try {
var ref = new ActionReference();
var d1 = new ActionDescriptor();
var d2 = new ActionDescriptor();
var ret = true;
try {
ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
d2.putUnitDouble( charIDToTypeID( "Hrzn" ), charIDToTypeID( "#Rlt" ), 0 );
d2.putUnitDouble( charIDToTypeID( "Vrtc" ), charIDToTypeID( "#Rlt" ), 0 );
d1.putReference( charIDToTypeID( "null" ), ref );
d1.putEnumerated( charIDToTypeID( "FTcs" ), charIDToTypeID( "QCSt" ), charIDToTypeID( "Qcsa" ) );
d1.putObject( charIDToTypeID( "Ofst" ), charIDToTypeID( "Ofst" ), d2 );
d1.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Prc" ), 100 );
d1.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Prc" ), 100 );
d1.putBoolean( charIDToTypeID( "Lnkd" ), false );
d1.putEnumerated( charIDToTypeID( "Intr" ), charIDToTypeID( "Intp" ), charIDToTypeID( "Bcbc" ) );
executeAction( charIDToTypeID( "Trnf" ), d1, DialogModes.ALL );
}
catch(e) { ret = false; }
return ret;
}
catch (e) { alert(e); throw(e); }
}
Copy link to clipboard
Copied
maybe i'm doing something wrong? still doesn't work:
2 layers:
i transformed one:
after activating the script nothing changes:
Copy link to clipboard
Copied
You do not have to transform manually. You must transform it through a script (it calls the transformation itself)
Copy link to clipboard
Copied
i got it now.
the script does great job, but i need something slightly different, I need to not transform the first layer within the script, given you have 2 layers one is already transformed and the second is not, i want the second one will adopt the first one
Copy link to clipboard
Copied
any ideas?
Copy link to clipboard
Copied
It is assumed that the smartobject "Layer 2" has a straight-angle border shape and has no rotations or distortions.
After you transform the "Layer 1" smartobject, run the script.
The layer "Layer 2" will take the form of a layer "Layer 1".
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObjectMore"));
r.putName(stringIDToTypeID("layer"), "Layer 1");
var list1 = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")).getList(stringIDToTypeID("nonAffineTransform"));
var p1 = new Array();
for (var i = 0; i < list1.count; i+=2) p1.push([list1.getDouble(i), list1.getDouble(i+1)]);
var r = new ActionReference();
r.putProperty(stringIDToTypeID("property"), stringIDToTypeID("smartObjectMore"));
r.putName(stringIDToTypeID("layer"), "Layer 2");
var list2 = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")).getList(stringIDToTypeID("nonAffineTransform"));
var p2 = new Array();
for (var i = 0; i < list2.count; i+=2) p2.push([list2.getDouble(i), list2.getDouble(i+1)]);
activeDocument.activeLayer = activeDocument.layers.getByName("Layer 2");
/// WITHOUT THIS, IT CAN BE BUGGY WTF??? ///////
var doc = activeDocument;
executeAction(stringIDToTypeID("placedLayerEditContents"), undefined, DialogModes.NO);
activeDocument.suspendHistory("", "");
activeDocument.close(SaveOptions.SAVECHANGES);
activeDocument = doc;
///////////////////////////////////////////////
var d = new ActionDescriptor();
var l = new ActionList();
l.putUnitDouble(charIDToTypeID("#Pxl"), p2[0][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p2[1][1]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p2[2][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p2[3][1]);
d.putList(stringIDToTypeID("rectangle"), l );
var l = new ActionList();
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[0][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[0][1]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[1][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[1][1]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[2][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[2][1]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[3][0]);
l.putUnitDouble(charIDToTypeID("#Pxl"), p1[3][1]);
d.putList(stringIDToTypeID("quadrilateral"), l);
var b0 = activeDocument.activeLayer.bounds;
executeAction(stringIDToTypeID("transform"), d, DialogModes.NO);
var b1 = activeDocument.activeLayer.bounds;
activeDocument.activeLayer.translate(b0[0] - b1[0], b0[1] - b1[1]);
Copy link to clipboard
Copied
Works! Thank you
Copy link to clipboard
Copied
can we change it from "Layer 1" and "Layer 2" to change active layer to the layer under it?
Copy link to clipboard
Copied
Please help Im trying to do this on photoshop 2022 version 23.5.2 Everytime after running the script I get Error 1302: no such element. Line: 25
->activeDocument.layer.getByname("Layer2");
I mean is there any other way or script to do this in photoshop? Really need this to work somehow without searching layer 1 or layer 2 image names and use it in script. I just want to copy tranforms from one scaled, skewed layer to same layer with no tranformations. Thanks for Help!
Copy link to clipboard
Copied
I want to change the script.
Can have it sync multiple selected layers
Copy link to clipboard
Copied
I want to change the script.
Can have it sync multiple selected layers
Causes transformation of the current smart-object. Then it repeats the transformation to all smart objects within the current level of nesting (Current Layer Set or Document)
var old_units = app.preferences.rulerUnits;
app.activeDocument.suspendHistory("Transform similar", "transform_similar()");
app.preferences.rulerUnits = old_units;
///////////////////////////////////////////////////////////////////////////////////////////
function transform_similar()
{
try {
if (app.activeDocument.activeLayer.kind != LayerKind.SMARTOBJECT)
{
alert("A Smart Object is required")
return;
}
app.preferences.rulerUnits = Units.CM;
var layer0 = app.activeDocument.activeLayer;
var parent = layer0.parent;
var len = parent.artLayers.length;
var x0 = layer0.bounds[0].value;
var y0 = layer0.bounds[1].value;
if (!transform()) return;
for (var i = 0; i < len; i++)
{
if (parent.artLayers == layer0) continue;
if (parent.artLayers.kind != LayerKind.SMARTOBJECT) continue;
app.activeDocument.activeLayer = parent.artLayers;
transform_again(x0, y0);
}
app.activeDocument.activeLayer = layer0;
}
catch (e) { alert(e); }
}
///////////////////////////////////////////////////////////////////////////////////////////
function transform_again(x0, y0)
{
try {
var layer = app.activeDocument.activeLayer;
var x1 = layer.bounds[0].value;
var y1 = layer.bounds[1].value;
move(x0-x1, y0-y1)
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
d.putBoolean(stringIDToTypeID("lastTransform"), true);
executeAction(stringIDToTypeID("transform"), d, DialogModes.NO);
move(x1-x0, y1-y0);
return true;
}
catch (e) { alert(e); return false; }
}
///////////////////////////////////////////////////////////////////////////////////////////
function move(x, y)
{
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
var d1 = new ActionDescriptor();
d1.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("distanceUnit"), x*72/2.54);
d1.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("distanceUnit"), y*72/2.54);
d.putObject(stringIDToTypeID("to"), stringIDToTypeID("offset"), d1);
executeAction(stringIDToTypeID("move"), d, DialogModes.NO);
}
catch (e) { alert(e); throw(e); }
}
////////////////////////////////////////////////////////////////////////////////////////////
function transform()
{
try {
var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
d.putEnumerated(stringIDToTypeID("freeTransformCenterState"), stringIDToTypeID("quadCenterState"), stringIDToTypeID("QCSAverage"));
var d1 = new ActionDescriptor();
d1.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("distanceUnit"), 0);
d1.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("distanceUnit"), 0);
d.putObject(stringIDToTypeID("offset"), stringIDToTypeID("offset"), d1);
d.putUnitDouble(stringIDToTypeID("width"), stringIDToTypeID("percentUnit"), 100);
d.putUnitDouble(stringIDToTypeID("height"), stringIDToTypeID("percentUnit"), 100);
d.putBoolean(stringIDToTypeID("linked"), false);
d.putEnumerated(charIDToTypeID("Intr"), stringIDToTypeID("interpolationType"), stringIDToTypeID("bicubic"));
executeAction(stringIDToTypeID("transform"), d, DialogModes.ALL);
return true;
}
catch(e) { return false; }
}
Copy link to clipboard
Copied
There is a saying in China.
A designer who does not code is a fake designer.
Really hard to beat you, you are really great!
Copy link to clipboard
Copied
What should I do?