Skip to main content
markk9596665
Participating Frequently
May 20, 2015
Answered

How can I retrieve the transform information on a layer

  • May 20, 2015
  • 6 replies
  • 9570 views

I am trying to retrieve the transformation information on a layer through script (for a smart object if it matters).

 

I've been able to do it if there is a text layer attached, but I need to be able to do it with just the smart object.

 

This is what I have so far:

var idnull = charIDToTypeID("null");
var layerReference = new ActionReference();
layerReference.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var layerDescriptor = new ActionDescriptor();
layerDescriptor.putReference(idnull, layerReference);
layerDescriptor.putEnumerated(charIDToTypeID("FTcs"), charIDToTypeID("QCSt"), charIDToTypeID("Qcsa"));
var transformDescriptor = app.executeAction(charIDToTypeID("Trnf"), layerDescriptor, DialogModes.NO);
var offset= transformDescriptor.getObjectValue(charIDToTypeID("Ofst"));
var horizontalOffset = offset.getUnitDoubleValue(charIDToTypeID("Hrzn"));
var verticalOffset = offset.getUnitDoubleValue(charIDToTypeID("Vrtc"));

 

However, horizontalOffset and verticalOffset are both returned as zero.

 

Thanks in advance, Mark.

This topic has been closed for replies.
Correct answer c.pfaffenbichler

c.pfaffenbichler wrote:

I'd really just like to pull out the existing transformations applied to the layer.

I’m confident that information is not stored with the Layer, not even with a Smart Object, because the Layer’s position at some previous time is generally irrelevant.

Rotation, Scale, Skew, … are different for a Smart Object naturally – unfortunately they can not be directly retrieved as fas as I know.

And Type Layers are special cases anyhow.

However, if I open the free transform tool on the smart object, the current transformations (e.g., x, y, rotational angle, scale, etc) are all available, so they must be stored somewhere associated with that smart object.

Basically I need to replace the smart object with the layers in the smart object and transform them in such a way that they match the transformations applied to the smart object.  I want to actually extract the layers, and not just edit the linked SO.


if I open the free transform tool on the smart object, the current transformations (e.g., x, y, rotational angle, scale, etc)

But x and y are not related to the offset of a previous transformation, but the current position.

And as I already mentioned this information is not Script-accessible to the best of my knowledge (and others have tried, too).

Basically I need to replace the smart object with the layers in the smart object and transform them in such a way that they match the transformations applied to the smart object.  I want to actually extract the layers, and not just edit the linked SO.

I think you are going about this less than ideally, especially as Warps, perspectival transformations etc. might be difficult to evaluate.

One can use "New Smart Object via Copy" instead, open the SO and hide all but one Layer, save, rasterize, repeat for the next Layer etc.

I even attempted a Script on that basis once, but Groups, Layer Masks on Groups and Adjustment Layers, Clipping Masks etc. proved a bit difficult to handle …

6 replies

NB, colourmanagement
Community Expert
Community Expert
February 1, 2020

Hi

 

in any case, it seems its worth pointing out that once scaled, bitmap pixels are gone - so rescaling back to the original size is not loss-less

 

thanks

neil barstow, colourmanagement.net

[please do not use the reply button on a message in the thread, only use the one at the top of the page, to maintain chronological order]

schroef
Inspiring
February 6, 2020

Well examples show using a smartObject, not even sure what you mean by "Bitmap pixels are gone"???

Participating Frequently
April 20, 2018

from cc 2015, we can get 4 points coordinates of smartobject layer

1. then we can calculate the angle

2. we can calculate the size of current smartobject layer,  we can also get the original size of smartobject by action manager, so "current size/original size" is the scale

ExtendScript-Helper/smartobject.jsx at master · songgeb/ExtendScript-Helper · GitHub

JJMack
Community Expert
Community Expert
April 20, 2018

There are problem with that script's function    getSmartObjectScale  getgetSmartObjectScaleSmartObjectScale getSmartObjectScale  getSmartObjectScale.

function getSmartObjectScale (layer) {

    if (layer.kind != LayerKind.SMARTOBJECT) {alert("layer is not smart object!"); return null;}

     var originalActiveLayer = app.activeDocument.activeLayer;

     app.activeDocument.activeLayer = layer;

     //获取智能对象当前尺寸

     var originalSize = getSmartObjectSize (layer);

    //进入智能对象编辑页面,获取智能对象原尺寸

    var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );

    var desc1900 = new ActionDescriptor();

    executeAction( idplacedLayerEditContents, desc1900, DialogModes.NO );//进入对象编辑页面

    //获取文档大小

    var width = app.activeDocument.width.value;

    var height = app.activeDocument.height.value;

    app.activeDocument.close (SaveOptions.DONOTSAVECHANGES);

    app.activeDocument.activeLayer = originalActiveLayer;

   

    return {"width": originalSize.width/width, "height": originalSize.height/height};

}

All smart object layers are not the same. There are different type of objects.  That script function opens the active layer object "placedLayerEditContents" that is a problem.  All object will not be opened by Photoshop.  A placed image file may not open in Photoshop.  My test document had a Placed RAW file when the script function open the object  I was then in ACR when I click OK the function closed the current document in Photoshop and there was no open Document in Photoshop.  Likewise with a vector smart object layer a placed .svg file the SVG was opend in Internet Eplorer on my machine and when I closed IE the function close the current document and nothing was open in Photoshop.

When my smart object layer was a placed Jpeg file the function  getSmartObjectScale   would only get the scale correct when the Documents DPI and the Jpeg same the same DPI.

I added thie alert to your script so you can see the scale isn not correct.

alert("scale " + scale.width + " " + scale.height + "\n"

     + "size " + size.width + " " + size.height + "\n"

     + "corners " + corners + "\n"

     + "bounds " + bounds + "\n"

     + "angle " + angle);

Here is a screen capture shows the Placed jpeg place transform in the tool option bar then I ran your script and then an other script like your that rounds values gets the scaling right and it works with all object types for it does not open the objects. Vector Smart Opbects have not size.  Devision by 0 is infinity so theat script shows infinity as yje scale value not what the Place transfom shows.  Photoshop must set some size for Places .svg and .ai files.  I was unable to figure out how Photoshop handled placed vector files like .svg and .ai files.

A Placed SVG file Follows

JJMack
Participating Frequently
April 23, 2018

Thanks for your reply!

PS can not open svg smart object layer. But we can export the original svg file by action manager. Then open it again by ps. So we can get its size.

var idplacedLayerExportContents = stringIDToTypeID( "placedLayerExportContents" );

var desc3027 = new ActionDescriptor();

var idnull = charIDToTypeID( "null" );

desc3027.putPath( idnull, new File( "/Users/admin/xxx.svg" ) );

executeAction( idplacedLayerExportContents, desc3027, DialogModes.NO );

JJMack
Community Expert
Community Expert
April 18, 2018

Have you been able to do it?  Using what r-bin posted for a smart object layer if it is rectangular you should be able to get the object's width and height scaling and angle of rotation, If it been distorted with some perspective or warp I think it very hard or impossible to deal with.  Even it is rectangular I do not know if it would be easy to determine if it has been flipped vertically or horizontally.

Photoshop also does some scaling when the object resolution is not the same as the document resolution. I have been able to figured  exactly what Photoshop does whet there is a resolution mismatch.   After I place in image in a script I always  the smart object layers associated transform to 100% width and height. so I know the object size using layer bounds. and know it the object is it full size and work from there. I know I can resized it the way I need to then.

By look at the four corners x y in order you can tell if the layer has been flipped. However the layer can be flipped horizontally or vertically also be rotated and the object and documents can have different resolutions.  Telling what is what  is complex.

JJMack
JJMack
Community Expert
Community Expert
April 19, 2018

Here an Smart Object image layer with no rotation straight up portrait and not flipped,   then flipped horizontally, then flipped vertically, and then flipped  horizontally and  vertically.  Screen Capture shows the Smart object layers Transform setting in the tool option bar.  Also screen captures that show Information a script can retrieved using the action manager code r-bin posted for retrieving the objects dour corners and some of the additional smart object information available. By comparing the x,y corner points positions relative to each other in order one would be able to figure out if any flipping was done. However as shown in my previous append throwing in rotation may make it much harder rotation 90, 180, 270 may look like flipping or 180 may look lo 0 and 270 look like 90.

JJMack
Participant
April 18, 2018

Hi. Have read many threads about this. But haven't find any solution. So do you have any luck with your issue?

I have a smartObject which is flipped horizontally. And I need get a current width value. If it have "-" smartObject is flipped.

Can anyone help me with this?

Thanks in advance.

JJMack
Community Expert
Community Expert
April 18, 2018

If you are using CC 2018, r-bin posted some action manager code the can get the  four corners of your smart object layer.  For me he also posted more code about other smart object information can be retrieved.  You may want to search for those threads. I just hack at javascript I do not know it.

From the four corners you can determine if the Object  has been rotated or not.  You can get the length of the sides and the slopes of the side to see it the are parallel and see if they form a rectangle.  Some of the information about the information retrieved about the Smart included it actual size.  So you may be able to calculate and scaling done if the smart object is still a rectangle.  I did not go ther far.

Here is a hack I did using his code. It will give you the four side and their slopes.  The script only used his code for the objects four corners the other code he posted is not in this hack.

// Explore Smart Object Layer's 4 corner-points (x,y)

/////////////////////////////////////////////////////

CheckVersion(19);

if (app.activeDocument.activeLayer.kind!=LayerKind.SMARTOBJECT) alert("ActiveLayer not Smart Object Layer");

else {

cTID = function(s) { return app.charIDToTypeID(s); };

    sTID = function(s) { return app.stringIDToTypeID(s); };

var orig_ruler_units = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS; // Set the ruler units to PIXELS

var res = app.activeDocument.resolution;

app.activeDocument.resizeImage(app.activeDocument.width.value,app.activeDocument.height.value,72);

var points = get_smart_object_corners();    // Get Smart Object layers corners

// Mark their (x,y)

clearGuides();                              // Clear Canvas Guides

MarkX( points[0][0]);

MarkY( points[0][1]);

MarkX( points[1][0]);

MarkY( points[1][1]);

MarkX( points[2][0]);

MarkY( points[2][1]);

MarkX( points[3][0]);

MarkY( points[3][1]);

// side line paths

var p00 = new Point(Math.round(points[0][0]), Math.round(points[0][1]));

var p10 = new Point(Math.round(points[1][0]), Math.round(points[1][1]));

var p01 = new Point(Math.round(points[2][0]), Math.round(points[2][1]));

var p11 = new Point(Math.round(points[3][0]), Math.round(points[3][1]));

var lineSubPathArray = new Array();

appendLine(p00, p10, lineSubPathArray);

appendLine2(p10, p01, lineSubPathArray);

appendLine2(p01, p11, lineSubPathArray);

appendLine3(p11, p00, lineSubPathArray);

createPathLayer("Object Side line Path", lineSubPathArray);

app.activeDocument.selection.select(points);// Set new selection  using layers corners

//SelectionToPath(); // Set Work Path not so good

Workpath(points[0][0],points[0][1],points[1][0],points[1][1],points[2][0],points[2][1],points[3][0],points[3][1]);

// get the slope and length of the layers sides 0 is horizontal 90 is vertical

var w = points[0][0] - points[1][0];

var h = points[0][1] - points[1][1];

var l0 = Math.sqrt(Math.pow(w,2)+Math.pow(h,2));

var angle0 = Math.atan(h/w) * 180.0 / Math.PI;

var w = points[1][0] - points[2][0] ;

var h = points[1][1] - points[2][1] ;

var l1 = Math.sqrt(Math.pow(w,2)+Math.pow(h,2));

var angle1 = Math.atan(h/w) * 180.0 / Math.PI;

var w = points[2][0] - points[3][0] ;

var h = points[2][1] - points[3][1] ;

var l2 = Math.sqrt(Math.pow(w,2)+Math.pow(h,2));

var angle2 = Math.atan(h/w) * 180.0 / Math.PI;

var w = points[3][0] - points[0][0] ;

var h = points[3][1] - points[0][1] ;

var l3 = Math.sqrt(Math.pow(w,2)+Math.pow(h,2));

var angle3 = Math.atan(h/w) * 180.0 / Math.PI;

//prerimmeter length

var l4 = l0+l1+l2+l3;

//show the user this information

alert( Math.round(points[0][0]) + ", " +  Math.round(points[0][1]) + " "

+ angle0.toFixed(0) + "° " + l0.toFixed(2) +"\n\n"

+ Math.round(points[1][0]) + ", " +  Math.round(points[1][1]) + " "

+ angle1.toFixed(1) + "° " + l1.toFixed(2) +"\n\n"

+ Math.round(points[2][0]) + ", " +  Math.round(points[2][1]) + " "

+ angle2.toFixed(1) + "° " + l2.toFixed(2) +"\n\n"

+ Math.round(points[3][0]) + ", " +  Math.round(points[3][1]) + " "

+ angle3.toFixed(1) + "° " + l3.toFixed(2) +"\n\n"

+ l4.toFixed(2));

app.activeDocument.resizeImage(app.activeDocument.width.value,app.activeDocument.height.value,res);

app.preferences.rulerUnits = orig_ruler_units; // Reset units to original settings

}

////////////////////////////////////////////////////////////////////////////////////////////////////////

// function get_smart_object_corners() returns array from 4 corner-points (x,y)

// of smart object in pixels (value with floating point) https://forums.adobe.com/people/r-bin

////////////////////////////////////////////////////////////////////////////////////////////////////////

function get_smart_object_corners() {

    try{

        var r = new ActionReference();

        r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );

        var d;

        try { d = executeActionGet(r); } catch (e) { alert(e); return; }

        try { d = d.getObjectValue(stringIDToTypeID("smartObjectMore"));    } catch (e) { alert(e); return; }

        try { d = d.getList(stringIDToTypeID("nonAffineTransform"));                 } catch (e) { alert(e); return; }

        var ret = [[d.getDouble(0),d.getDouble(1)],

                   [d.getDouble(2),d.getDouble(3)],

                   [d.getDouble(4),d.getDouble(5)],

                   [d.getDouble(6),d.getDouble(7)]];

        return ret;

    }

    catch (e) { alert(e); }

}

function clearGuides() {

   var id556 = charIDToTypeID( "Dlt " );

       var desc102 = new ActionDescriptor();

       var id557 = charIDToTypeID( "null" );

           var ref70 = new ActionReference();

           var id558 = charIDToTypeID( "Gd  " );

           var id559 = charIDToTypeID( "Ordn" );

           var id560 = charIDToTypeID( "Al  " );

           ref70.putEnumerated( id558, id559, id560 );

       desc102.putReference( id557, ref70 );

   executeAction( id556, desc102, DialogModes.NO );

};

function MarkX(x) {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc61 = new ActionDescriptor();

    var idNw = charIDToTypeID( "Nw  " );

        var desc62 = new ActionDescriptor();

        var idPstn = charIDToTypeID( "Pstn" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc62.putUnitDouble( idPstn, idPxl, x);

        var idOrnt = charIDToTypeID( "Ornt" );

        var idOrnt = charIDToTypeID( "Ornt" );

        var idVrtc = charIDToTypeID( "Vrtc" );

        desc62.putEnumerated( idOrnt, idOrnt, idVrtc );

    var idGd = charIDToTypeID( "Gd  " );

    desc61.putObject( idNw, idGd, desc62 );

executeAction( idMk, desc61, DialogModes.NO );

}

function MarkY(y) {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc63 = new ActionDescriptor();

    var idNw = charIDToTypeID( "Nw  " );

        var desc64 = new ActionDescriptor();

        var idPstn = charIDToTypeID( "Pstn" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc64.putUnitDouble( idPstn, idPxl, y );

        var idOrnt = charIDToTypeID( "Ornt" );

        var idOrnt = charIDToTypeID( "Ornt" );

        var idHrzn = charIDToTypeID( "Hrzn" );

        desc64.putEnumerated( idOrnt, idOrnt, idHrzn );

    var idGd = charIDToTypeID( "Gd  " );

    desc63.putObject( idNw, idGd, desc64 );

executeAction( idMk, desc63, DialogModes.NO );

}

function SelectionToPath() {

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc1145 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref692 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        ref692.putClass( idPath );

    desc1145.putReference( idnull, ref692 );

    var idFrom = charIDToTypeID( "From" );

        var ref693 = new ActionReference();

        var idcsel = charIDToTypeID( "csel" );

        var idfsel = charIDToTypeID( "fsel" );

        ref693.putProperty( idcsel, idfsel );

    desc1145.putReference( idFrom, ref693 );

    var idTlrn = charIDToTypeID( "Tlrn" );

    var idPxl = charIDToTypeID( "#Pxl" );

    desc1145.putUnitDouble( idTlrn, idPxl, 2.000000 );

executeAction( idMk, desc1145, DialogModes.NO );

}

function Point(x, y) {

this.x = x;

this.y = y;

}

function addVertexCorner(lineArray, x, y) {

var p0Info = new PathPointInfo();

lineArray.push(p0Info);

p0Info.kind = PointKind.CORNERPOINT;

p0Info.anchor = new Array(x, y);

p0Info.leftDirection = p0Info.anchor;

p0Info.rightDirection = p0Info.anchor;

}

function appendLine(p0, p1, lineSubPathArray) {

var lineArray = new Array();

addVertexCorner(lineArray, p0.x, p0.y);

addVertexCorner(lineArray, p1.x, p1.y);

var pathInfo = new SubPathInfo();

lineSubPathArray.push(pathInfo);

pathInfo.operation = ShapeOperation.SHAPEADD;

pathInfo.closed = false;

pathInfo.entireSubPath = lineArray;

}

function appendLine2(p0, p1, lineSubPathArray) {

var lineArray = new Array();

addVertexCorner(lineArray, p0.x, p0.y);

addVertexCorner(lineArray, p1.x, p1.y);

var pathInfo = new SubPathInfo();

lineSubPathArray.push(pathInfo);

pathInfo.operation = ShapeOperation.SHAPEINTERSECT;

pathInfo.closed = false;

pathInfo.entireSubPath = lineArray;

}

function appendLine3(p0, p1, lineSubPathArray) {

var lineArray = new Array();

addVertexCorner(lineArray, p0.x, p0.y);

addVertexCorner(lineArray, p1.x, p1.y);

var pathInfo = new SubPathInfo();

lineSubPathArray.push(pathInfo);

pathInfo.operation = ShapeOperation.SHAPEINTERSECT;

pathInfo.closed = true;

pathInfo.entireSubPath = lineArray;

}

function createPathLayer(title, subPathArray) {

var docRef = app.activeDocument;

var myPathItem = docRef.pathItems.add(title, subPathArray);

}

// Set Work Path four corner points no handles

function Workpath(x0,y0,x1,y1,x2,y2,x3,y3) {

    var desc1 = new ActionDescriptor();

    var ref1 = new ActionReference();

    ref1.putProperty(cTID('Path'), cTID('WrPt'));

    desc1.putReference(cTID('null'), ref1);

    var list1 = new ActionList();

    var desc2 = new ActionDescriptor();

    desc2.putEnumerated(sTID("shapeOperation"), sTID("shapeOperation"), cTID('Add '));

    var list2 = new ActionList();

    var desc3 = new ActionDescriptor();

    desc3.putBoolean(cTID('Clsp'), true);

    var list3 = new ActionList();

    var desc4 = new ActionDescriptor();

    var desc5 = new ActionDescriptor();

    desc5.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), x1);

    desc5.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), y1);

    desc4.putObject(cTID('Anch'), cTID('Pnt '), desc5);

    list3.putObject(cTID('Pthp'), desc4);

    var desc6 = new ActionDescriptor();

    var desc7 = new ActionDescriptor();

    desc7.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), x2);

    desc7.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), y2);

    desc6.putObject(cTID('Anch'), cTID('Pnt '), desc7);

    list3.putObject(cTID('Pthp'), desc6);

    var desc8 = new ActionDescriptor();

    var desc9 = new ActionDescriptor();

    desc9.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), x3);

    desc9.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), y3);

    desc8.putObject(cTID('Anch'), cTID('Pnt '), desc9);

    list3.putObject(cTID('Pthp'), desc8);

    var desc10 = new ActionDescriptor();

    var desc11 = new ActionDescriptor();

    desc11.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), x0);

    desc11.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), y0);

    desc10.putObject(cTID('Anch'), cTID('Pnt '), desc11);

    list3.putObject(cTID('Pthp'), desc10);

    desc3.putList(cTID('Pts '), list3);

    list2.putObject(cTID('Sbpl'), desc3);

    desc2.putList(cTID('SbpL'), list2);

    list1.putObject(cTID('PaCm'), desc2);

    desc1.putList(cTID('T   '), list1);

    executeAction(cTID('setd'), desc1, DialogModes.NO);

  };

// CheckVersion

function CheckVersion(PSV) {

var numberArray = version.split(".");

if ( numberArray[0] < PSV ) {

//alert( "You must use Photoshop " + PSV + " or later to run this script!" );

throw( "You must use Photoshop " + PSV + " or later to run this script!" );

}

}

JJMack
JJMack
Community Expert
Community Expert
April 18, 2018

This hack has his other Smart Object Information code in it.  You can see the smart object actual size bounds. All the other transformation warp and mesh stuff would fry my little brain if I tried to understand it. I rather drink some wine to make my head spin.

CheckVersion(19);

var r = new ActionReference();   

r.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );   

var obj = executeActionGet(r).getObjectValue(stringIDToTypeID("smartObjectMore")) 

 

with (obj) 

    { 

    var _tmp; 

 

    var id         = getString(stringIDToTypeID("ID")); 

    var placed     = getString(stringIDToTypeID("placed")); 

 

    var pageNumber = getInteger(stringIDToTypeID("pageNumber")); 

    var totalPages = getInteger(stringIDToTypeID("totalPages")); 

    var crop       = getInteger(stringIDToTypeID("crop")); 

 

    var frameCount    = getInteger(stringIDToTypeID("frameCount")); 

    var antiAliasType = getInteger(stringIDToTypeID("antiAliasType")); 

    var type          = getInteger(stringIDToTypeID("type")); 

 

    _tmp = getObjectValue(stringIDToTypeID("frameStep")); 

    var frameStep = new Object({ 

        numerator  : _tmp.getInteger(stringIDToTypeID("numerator")),  

        denominator: _tmp.getInteger(stringIDToTypeID("denominator")) 

        }); 

 

    _tmp = getObjectValue(stringIDToTypeID("duration")); 

    var duration = new Object({ 

        numerator  : _tmp.getInteger(stringIDToTypeID("numerator")),  

        denominator: _tmp.getInteger(stringIDToTypeID("denominator")) 

        }); 

 

    _tmp = getList(stringIDToTypeID("transform")); 

    var transform  = new Array();  

    for (var i = 0; i < _tmp.count; i+=2) transform.push([_tmp.getDouble(i), _tmp.getDouble(i+1)]);  

 

    _tmp = getList(stringIDToTypeID("nonAffineTransform")); 

    var nonAffineTransform  = new Array();  

    for (var i = 0; i < _tmp.count; i+=2) nonAffineTransform.push([_tmp.getDouble(i), _tmp.getDouble(i+1)]);  

 

    _tmp = getObjectValue(stringIDToTypeID("warp")); 

 

    var warp = new Object({ 

        warpStyle:            typeIDToStringID(_tmp.getEnumerationValue(stringIDToTypeID("warpStyle"))),  

        warpValue:            _tmp.getDouble(stringIDToTypeID("warpValue")), 

        warpPerspective:      _tmp.getDouble(stringIDToTypeID("warpPerspective")), 

        warpPerspectiveOther: _tmp.getDouble(stringIDToTypeID("warpPerspective")), 

        warpRotate:           typeIDToStringID(_tmp.getEnumerationValue(stringIDToTypeID("warpRotate"))),  

        uOrder:               _tmp.getInteger(stringIDToTypeID("uOrder")), 

        vOrder:               _tmp.getInteger(stringIDToTypeID("vOrder")), 

 

        bounds: new Object({  

            top   : _tmp.getObjectValue(stringIDToTypeID("bounds")).getUnitDoubleValue(stringIDToTypeID("top")), 

            left  : _tmp.getObjectValue(stringIDToTypeID("bounds")).getUnitDoubleValue(stringIDToTypeID("left")), 

            bottom: _tmp.getObjectValue(stringIDToTypeID("bounds")).getUnitDoubleValue(stringIDToTypeID("bottom")), 

            right : _tmp.getObjectValue(stringIDToTypeID("bounds")).getUnitDoubleValue(stringIDToTypeID("right")), 

            }), 

        }); 

 

    warp.meshPoints = new Array(); 

 

    try { // may be absent 

        _tmp = _tmp.getObjectValue(stringIDToTypeID("customEnvelopeWarp")).getList(stringIDToTypeID("meshPoints")); 

        for (var i = 0; i < _tmp.count; i++)  

            { 

            var x = _tmp.getObjectValue(i); 

            warp.meshPoints.push([x.getUnitDoubleValue(stringIDToTypeID("horizontal")), x.getUnitDoubleValue(stringIDToTypeID("vertical"))]);  

            } 

        } 

    catch(e) {} 

 

    _tmp = getObjectValue(stringIDToTypeID("size")); 

    var size = new Object({ 

        width:  _tmp.getDouble(stringIDToTypeID("width")), 

        height: _tmp.getDouble(stringIDToTypeID("height")), 

        }); 

 

    var resolution = getUnitDoubleValue(stringIDToTypeID("resolution"));     

 

    var comp = getInteger(stringIDToTypeID("comp"));     

 

    _tmp = getObjectValue(stringIDToTypeID("compInfo")); 

 

    var compID = _tmp.getInteger(stringIDToTypeID("compID")); 

    var originalCompID = _tmp.getInteger(stringIDToTypeID("originalCompID")); 

 

    try { // may be absent 

       _tmp = _tmp.getList(stringIDToTypeID("compList")); 

         

        var compList = new Array(); 

 

        for (var i = 0; i < _tmp.count; i++)  

            { 

            var x = _tmp.getObjectValue(i); 

 

            x.getString (stringIDToTypeID("name")); 

            x.getInteger(stringIDToTypeID("ID")); 

            x.getString (stringIDToTypeID("comment")); 

 

            compList.push(new Object({ 

                name:    x.getString (stringIDToTypeID("name")), 

                ID:      x.getInteger(stringIDToTypeID("ID")), 

                comment: x.getString (stringIDToTypeID("comment")) 

                })); 

            } 

        } 

    catch(e) {} 

    } 

/*

if (app.activeDocument.resolution==resolution) {

var scale = app.activeDocument.width.value/size.width*100 ;

alert(app.activeDocument.width.value + " " + app.activeDocument.height.value + " "+ app.activeDocument.resolution + "\n"

+ size.width  + " " + size.height  + " " + resolution  + "\n" 

+ scale.toFixed(2) + "%" +  "\n"

+ warp.meshPoints.toSource() );   

}

else {

var scale = 0.0;

alert(app.activeDocument.width.value + " " + app.activeDocument.height.value + " "+ app.activeDocument.resolution + "\n"

+ size.width  + " " + size.height  + " " + resolution  + "\n" 

+ scale.toFixed(2) + "%" +  "\n"

+ warp.meshPoints.toSource() ); 

}

*/

// examples

alert (warp.toSource()) 

//alert (size.toSource()) 

//alert (resolution)  

/*

alert(id); 

alert(placed);

alert(pageNumber);

alert(totalPages);

alert(crop);

alert(frameCount);

alert(antiAliasType);

alert(type);

alert(frameStep.toSource());

alert(duration.toSource());

alert(transform);

alert(nonAffineTransform);

alert(comp);

alert(compID);

alert(originalCompID);

*/

// CheckVersion

function CheckVersion(PSV) {

var numberArray = version.split(".");

if ( numberArray[0] < PSV ) {

//alert( "You must use Photoshop " + PSV + " or later to run this script!" );

throw( "You must use Photoshop " + PSV + " or later to run this script!" );

}

}

JJMack
Participant
June 8, 2015

Oh man, I know your frustration.
I'm having the similar woes. However, I'm not looking to apply the information to another layer, but just read the data, for use in other ways.
I also, didnt expect to run into this problem, as when CTRL+T is used on a smart object, the relative scale and angle are visible in the "INFO" window. I figured it was an easy win to get the transforms. I was wrong.
I find myself lost in TypeID's and unclear class structures for smartObjects.  I just havent found any good reference for "getting" the property value, only ways of setting  it, sadly.

If you or anyone else are successful, I'd be very interested in a  solution also, likewise, if I stumble into it, I'll post it.

Inspiring
June 25, 2015

I've made a script that somehow took the informations from the Smart Layer's transforms,

you can check this post: Need help cleaning up a script and adding loop, there is a reply there explaining what the script is doing, till now is the only way I found to get these values without reading the binary of the psd.

Participant
June 25, 2015

thanx it worked for me!!

c.pfaffenbichler
Community Expert
Community Expert
May 20, 2015

Under which circumstances exactly does this provide the result you intend (what does "attached text layer" mean)? Could you post a screenshot with the Layers Panel visible?

Once a Layer has been moved that information may be in the History but as far as I can tell no space is wasted on storing that information with the Layer itself.

markk9596665
Participating Frequently
May 20, 2015

Sorry, here's some clarification.  If I use code found here How to extract layer rotation (transform) in jsx photoshop script? - Stack Overflow for retrieving the transform of the text layer "PixelSquid Diving Helmet" it will work.  What I'm trying to do is get the transform that's applied to the layer DivingHelmet.H03, basically the data that is available:

I'd like the information on the existing transformations applied to the object, not trying to apply a new transformation to it.

Thanks again,

Mark

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
May 20, 2015

c.pfaffenbichler wrote:

I'd really just like to pull out the existing transformations applied to the layer.

I’m confident that information is not stored with the Layer, not even with a Smart Object, because the Layer’s position at some previous time is generally irrelevant.

Rotation, Scale, Skew, … are different for a Smart Object naturally – unfortunately they can not be directly retrieved as fas as I know.

And Type Layers are special cases anyhow.

However, if I open the free transform tool on the smart object, the current transformations (e.g., x, y, rotational angle, scale, etc) are all available, so they must be stored somewhere associated with that smart object.

Basically I need to replace the smart object with the layers in the smart object and transform them in such a way that they match the transformations applied to the smart object.  I want to actually extract the layers, and not just edit the linked SO.


if I open the free transform tool on the smart object, the current transformations (e.g., x, y, rotational angle, scale, etc)

But x and y are not related to the offset of a previous transformation, but the current position.

And as I already mentioned this information is not Script-accessible to the best of my knowledge (and others have tried, too).

Basically I need to replace the smart object with the layers in the smart object and transform them in such a way that they match the transformations applied to the smart object.  I want to actually extract the layers, and not just edit the linked SO.

I think you are going about this less than ideally, especially as Warps, perspectival transformations etc. might be difficult to evaluate.

One can use "New Smart Object via Copy" instead, open the SO and hide all but one Layer, save, rasterize, repeat for the next Layer etc.

I even attempted a Script on that basis once, but Groups, Layer Masks on Groups and Adjustment Layers, Clipping Masks etc. proved a bit difficult to handle …