Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


How to calculate the new boundaries of an object after transformation?

Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

I have an object inside a layer, the initial boundaries of which are known, but I cannot get them directly (this is part of the image) . Object are described in the standard way in document coordinates - top, left, right, bottom. I need to perform a series of transformations of the entire layer and after that get the new coordinates of the object inside it (transformation in this case is only a change in scale, image rotation is not performed). I easily coped with move (x+dx) (y+dy), but I got stuck on the transformation with the center set manually (the coordinates of this point are known - x, y). It seems that I understand this combination of move + scale and a proportional change coordinates is required depending on their distance from the point x,y, but I cannot deduce the correct formula for calculating the new values ​​of top, left, right, bottom. Can someone help me with this?

2021-07-28_16-14-48.png

P.S. it is clear that we can copy an object to a new layer and perform its transformation with the same parameters as the main layer (this is how the script works at the moment), but I want to speed up the script and get rid of unnecessary transformations (that is, get coordinates by calculation )

TOPICS
Actions and scripting

Views

75

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Adobe Community Professional , Jul 28, 2021 Jul 28, 2021
this.transform = function (dX, dY, scale, x, y, subject) { (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum')); (d = new ActionDescriptor()).putReference(s2t('null'), r); d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent')); ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x); d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y); ...

Likes

Translate

Translate
Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

 this.transform = function (dX, dY, scale, x, y, subject) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent'));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
        d.putObject(s2t('position'), s2t('paint'), d1);
        (d2 = new ActionDescriptor()).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), dX);
        d2.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), dY);
        d.putObject(s2t('offset'), s2t('offset'), d2);
        d.putUnitDouble(s2t('width'), s2t('percentUnit'), scale);
        d.putUnitDouble(s2t('height'), s2t('percentUnit'), scale);
        d.putEnumerated(s2t('interfaceIconFrameDimmed'), s2t('interpolationType'), s2t('bicubic'));
        executeAction(s2t('transform'), d, DialogModes.NO);

        if (subject) {
            with (subject) {
                var dV = (height * scale / 100 - (bottom - top)),
                    dH = (width * scale / 100 - (right - left));
                top = top - (dV * (y - top) / height) + dY
                bottom = bottom + (dV * (bottom - y) / height) + dY
                left = left - (dH * (x - left) / width) + dX
                right = right + (dH * (right - x) / width) + dX
                height = height * scale / 100
                width = width * scale / 100
            }
    }

* where subject is object with bounding box coordinates

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

Can you edit your code to working version to let me try out it on some layer with an object inside?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

LATEST

It is difficult for me to provide a working code, since I am getting the coordinates of the object with the layer from another program. But there is no difference, you can just calculate the bounding rect of the current layer after transformation.

 

var lr = new AM('layer'),
subject = lr.descToObject(lr.getProperty('boundsNoEffects'));

lr.transform(100, 200, 150, 70, 120, subject)
var newBounds = lr.descToObject(lr.getProperty('boundsNoEffects'));
alert ('calculated:\ntop: '+subject.top +', left: ' +subject.left + ', right: ' + subject.right + ', bottom: ' + subject.bottom + '\nreal:\ntop: '
+newBounds.top +', left: ' +newBounds.left + ', right: ' +newBounds.right + ', bottom: ' + newBounds.bottom + '\nreal:\n')

function AM(target, order) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = s2t(target)
    
    this.getProperty = function (property, descMode, id, idxMode, parent, parentIdx) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        if (parent) r.putIndex(s2t(parent), parentIdx);
        return descMode ? executeActionGet(r) : getDescValue(executeActionGet(r), property)
    }

    this.descToObject = function (d) {
        var o = {}
        for (var i = 0; i < d.count; i++) {
            var k = d.getKey(i)
            o[t2s(k)] = getDescValue(d, k)
        }
        return o
    }

    this.transform = function (dX, dY, scale, x, y, subject) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent'));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
        d.putObject(s2t('position'), s2t('paint'), d1);
        (d2 = new ActionDescriptor()).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), dX);
        d2.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), dY);
        d.putObject(s2t('offset'), s2t('offset'), d2);
        d.putUnitDouble(s2t('width'), s2t('percentUnit'), scale);
        d.putUnitDouble(s2t('height'), s2t('percentUnit'), scale);
        d.putEnumerated(s2t('interfaceIconFrameDimmed'), s2t('interpolationType'), s2t('bicubic'));
        executeAction(s2t('transform'), d, DialogModes.NO);

        if (subject) {
            with (subject) {
                var dV = (height * scale / 100 - (bottom - top)),
                    dH = (width * scale / 100 - (right - left));
                top = top - (dV * (y - top) / height) + dY
                bottom = bottom + (dV * (bottom - y) / height) + dY
                left = left - (dH * (x - left) / width) + dX
                right = right + (dH * (right - x) / width) + dX
                height = height * scale / 100
                width = width * scale / 100
            }
        }
    }

    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return (d.getObjectValue(p));
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return [t2s(d.getEnumerationType(p)), t2s(d.getEnumerationValue(p))];
            default: break;
        };
    }
}

PS. I would like to recalculate coordinates after rotation. Now I don't need it, but one day it might come in handy.

 

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

What kind of layer is it? Do you mean by layer the entire gray area, while the blue square is an object with some x, y point inside? Or gray area is some background of other layer while the mentioned layer is a blue square, that said, the x, y object would be then an object?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Community Professional ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

gray area - layer, blue square - object in this layer

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines