• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

how can i transform the isosceles trapezoid to a rectangle by extensionscript?

Guest
Jun 06, 2017 Jun 06, 2017

Copy link to clipboard

Copied

perspective_correction_Script_001.jpg

i have many different Isosceles trapezoids?

listener:

var idTrnf = charIDToTypeID( "Trnf" ); 

    var desc48 = new ActionDescriptor(); 

    var idnull = charIDToTypeID( "null" ); 

        var ref21 = new ActionReference(); 

        var idLyr = charIDToTypeID( "Lyr " ); 

        var idOrdn = charIDToTypeID( "Ordn" ); 

        var idTrgt = charIDToTypeID( "Trgt" ); 

        ref21.putEnumerated( idLyr, idOrdn, idTrgt ); 

    desc48.putReference( idnull, ref21 ); 

    var idFTcs = charIDToTypeID( "FTcs" ); 

    var idQCSt = charIDToTypeID( "QCSt" ); 

    var idQcsa = charIDToTypeID( "Qcsa" ); 

    desc48.putEnumerated( idFTcs, idQCSt, idQcsa ); 

    var idOfst = charIDToTypeID( "Ofst" ); 

        var desc49 = new ActionDescriptor(); 

        var idHrzn = charIDToTypeID( "Hrzn" ); 

        var idPxl = charIDToTypeID( "#Pxl" ); 

        desc49.putUnitDouble( idHrzn, idPxl, -16.066570 ); 

        var idVrtc = charIDToTypeID( "Vrtc" ); 

        var idPxl = charIDToTypeID( "#Pxl" ); 

        desc49.putUnitDouble( idVrtc, idPxl, 16.381048 ); 

    var idOfst = charIDToTypeID( "Ofst" ); 

    desc48.putObject( idOfst, idOfst, desc49 ); 

    var idWdth = charIDToTypeID( "Wdth" ); 

    var idPrc = charIDToTypeID( "#Prc" ); 

    desc48.putUnitDouble( idWdth, idPrc, 134.475806 ); 

    var idSkew = charIDToTypeID( "Skew" ); 

        var desc50 = new ActionDescriptor(); 

        var idHrzn = charIDToTypeID( "Hrzn" ); 

        var idAng = charIDToTypeID( "#Ang" ); 

        desc50.putUnitDouble( idHrzn, idAng, 19.127500 ); 

        var idVrtc = charIDToTypeID( "Vrtc" ); 

        var idAng = charIDToTypeID( "#Ang" ); 

        desc50.putUnitDouble( idVrtc, idAng, 0.000000 ); 

    var idPnt = charIDToTypeID( "Pnt " ); 

    desc48.putObject( idSkew, idPnt, desc50 );

 

var idUsng = charIDToTypeID( "Usng" );

        var desc51 = new ActionDescriptor();

        var idHrzn = charIDToTypeID( "Hrzn" );

        var idPrc = charIDToTypeID( "#Prc" );

        desc51.putUnitDouble( idHrzn, idPrc, -0.000000 );

        var idVrtc = charIDToTypeID( "Vrtc" );

        var idPrc = charIDToTypeID( "#Prc" );

        desc51.putUnitDouble( idVrtc, idPrc, 0.655242 );  //0.655242 Represents the percentage of the vertical direction?How to calculate it,

    var idPnt = charIDToTypeID( "Pnt " );

    desc48.putObject( idUsng, idPnt, desc51 );

    var idPnt = charIDToTypeID( "Pnt " ); 

    desc48.putObject( idUsng, idPnt, desc51 ); 

    var idIntr = charIDToTypeID( "Intr" ); 

    var idIntp = charIDToTypeID( "Intp" ); 

    var idbicubicAutomatic = stringIDToTypeID( "bicubicAutomatic" ); 

    desc48.putEnumerated( idIntr, idIntp, idbicubicAutomatic ); 

executeAction( idTrnf, desc48, DialogModes.NO );

TOPICS
Actions and scripting

Views

1.1K

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
Guest
Jun 06, 2017 Jun 06, 2017

Copy link to clipboard

Copied

0.655242 Represents the percentage of the vertical direction?How to calculate it,

Votes

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
Enthusiast ,
Jun 07, 2017 Jun 07, 2017

Copy link to clipboard

Copied

I tried similar thing here: How to remove Smart Object deformation with scripting? | Photoshop Family Customer Community

Magic scripts for Photoshop

Anyway I can't solve this now. I can send you everything what I know now.

I am working on algorithm which start with big value and then try something, measure values and decrease or increase this value.

Binary search algorithm - Wikipedia

Then I could save a lot data for data analysis and find mathematic formula.

Votes

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
Enthusiast ,
Jun 07, 2017 Jun 07, 2017

Copy link to clipboard

Copied

You also can use "perspective warp" if you have single bitmap layer. Data from script listener here should be easy to change.

Votes

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
Community Expert ,
Jun 07, 2017 Jun 07, 2017

Copy link to clipboard

Copied

i have many different Isosceles trapezoids?

And what do we know about them?

Are they all of the same angles and width and height?

How do you intend to automate the task if they should differ?

Votes

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
Community Expert ,
Jun 10, 2017 Jun 10, 2017

Copy link to clipboard

Copied

Sorry, the previous formula was nonsense …

distortIsoscelesTrapezoidsScr.jpg

// 2017, use it at your own risk;

#target photoshop

// from adobe’s terminology.jsx;

const classChannel = app.charIDToTypeID('Chnl');

const classRectangle = app.charIDToTypeID('Rctn');

const enumNone = app.charIDToTypeID('None');

const eventSet = app.charIDToTypeID('setd');

const eventTransform = app.charIDToTypeID('Trnf');

const keySelection = app.charIDToTypeID('fsel');

const krectangleStr = app.stringIDToTypeID("rectangle");

const kquadrilateralStr = app.stringIDToTypeID("quadrilateral");

const keyBottom = app.charIDToTypeID('Btom');

const keyLeft = app.charIDToTypeID('Left');

const keyNull = app.charIDToTypeID('null');

const keyRight = app.charIDToTypeID('Rght');

const keyTo = app.charIDToTypeID('T   ');

const keyTop = app.charIDToTypeID('Top ');

const typeOrdinal = app.charIDToTypeID('Ordn');

const unitPixels = app.charIDToTypeID('#Pxl');

// from adobe’s geometry.jsx;

//

// =================================== TPoint ===================================

//

function TPoint( x, y )

{

  this.fX = x;

  this.fY = y;

}

// TPoint Constants

const kTPointOrigion = new TPoint( 0, 0 );

TPoint.kOrigin = kTPointOrigion;

const kTPointInfinite = new TPoint( Infinity, Infinity );

TPoint.kInfinite = kTPointInfinite;

const kTPointClassname = "TPoint";

TPoint.prototype.className = kTPointClassname;

// Overloaded math operators

TPoint.prototype["=="] = function( Src )

{

  return (this.fX == Src.fX) && (this.fY == Src.fY);

}

TPoint.prototype["+"] = function( b )

{

  return new TPoint( this.fX + b.fX, this.fY + b.fY );

}

TPoint.prototype["-"] = function( b, reversed )

{

  if (typeof(b) == "undefined")

// unary minus

  return new TPoint( -this.fX, -this.fY )

  else

  {

  if (reversed)

  return new TPoint( b.fX - this.fX, by.fY - this.fY );

  else

  return new TPoint( this.fX - b.fX, this.fY - b.fY);

  }

}

//

// Multiply and divide work with scalars as well as points

//

TPoint.prototype["*"] = function( b )

{

    if (typeof(b) == 'number')

  return new TPoint( this.fX * b, this.fY * b );

  else

  return new TPoint( this.fX * b.fX, this.fY * b.fY );

}

TPoint.prototype["/"] = function( b, reversed )

{

  if (reversed)

  {

  if (typeof(b) == "number")

  debugger;

// Can't divide a number by a point

  else

  return new TPoint( b.fX / this.fX, b.fY / this.fY );

  }

  else

  {

  if (typeof(b) == 'number')

  return new TPoint( this.fX / b, this.fY / b );

  else

  return new TPoint( this.fX / b.fX, this.fY / b.fY );

  }

}

TPoint.prototype.toString = function()

{

  return "[" + this.fX.toString() + "," + this.fY.toString() + "]";

}

TPoint.prototype.vectorLength = function()

{

    return Math.sqrt( this.fX * this.fX + this.fY * this.fY );

}

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

var myDocument = app.activeDocument;

// deselect;

try {

myDocument.selection.deselect();

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

var idDslc = charIDToTypeID( "Dslc" );

    var desc4 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        ref2.putClass( idPath );

    desc4.putReference( idnull, ref2 );

executeAction( idDslc, desc4, DialogModes.NO );

}

catch (e) {};

// switch units to pixels;

app.preferences.rulerUnits = Units.PIXELS;

//////////// transformation ////////////

try {

// paste the image into the document;

var theScreenImage = myDocument.activeLayer;

//////////// corners ////////////

// get the horicontal and vertical coordinates in pixels;

var theBounds = theScreenImage.bounds;

var theWidth = theBounds[2] - theBounds[0];

var thePerc = 58.4;

var theOffset = ((theWidth / thePerc * 100) - theWidth) /2;

var x1 = theBounds[0] - theOffset;

var y1 = theBounds[1];

var x2 = theBounds[2] + theOffset;

var y2 = theBounds[1];

var x3 = theBounds[2];

var y3 = theBounds[3];

var x4 = theBounds[0];

var y4 = theBounds[3];

//////////// transform to the new corners ////////////

transformActiveLayer( [new TPoint(x1,y1), new TPoint(x2,y2), new TPoint(x3,y3), new TPoint(x4,y4)]);

// resets the preferences units;

app.preferences.rulerUnits = originalUnits;

}

catch (e) {};

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

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

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

//////////// the  functions ////////////

// from adobe’s stacksupport.jsx;

// Apply a perspective transform to the current layer, with the

// corner TPoints given in newCorners (starts at top left, in clockwise order)

// Potential DOM fix

function transformActiveLayer( newCorners )

{

  function pxToNumber( px )

  {

  return px.as("px");

  }

  var saveUnits = app.preferences.rulerUnits;

  app.preferences.rulerUnits = Units.PIXELS;

  var i;

  var setArgs = new ActionDescriptor();

  var chanArg = new ActionReference();

  chanArg.putProperty( classChannel, keySelection );

  var boundsDesc = new ActionDescriptor();

  var layerBounds = app.activeDocument.activeLayer.bounds;

  boundsDesc.putUnitDouble( keyTop, unitPixels, pxToNumber( layerBounds[1] ) );

  boundsDesc.putUnitDouble( keyLeft, unitPixels, pxToNumber( layerBounds[0] ) );

  boundsDesc.putUnitDouble( keyRight, unitPixels, pxToNumber( layerBounds[2] ) );

  boundsDesc.putUnitDouble( keyBottom, unitPixels, pxToNumber( layerBounds[3] ) );

  var result = new ActionDescriptor();

  var args = new ActionDescriptor();

  var quadRect = new ActionList();

  quadRect.putUnitDouble( unitPixels, pxToNumber( layerBounds[0] ) );

// ActionList put is different from ActionDescriptor put

  quadRect.putUnitDouble( unitPixels, pxToNumber( layerBounds[1] ) );

  quadRect.putUnitDouble( unitPixels, pxToNumber( layerBounds[2] ) );

  quadRect.putUnitDouble( unitPixels, pxToNumber( layerBounds[3] ) );

  var quadCorners = new ActionList();

  for (i = 0; i < 4; ++i)

  {

  quadCorners.putUnitDouble( unitPixels, newCorners.fX );

  quadCorners.putUnitDouble( unitPixels, newCorners.fY );

  }

  args.putList( krectangleStr, quadRect );

  args.putList( kquadrilateralStr, quadCorners );

  executeAction( eventTransform, args );

// Deselect

  deselArgs = new ActionDescriptor();

  deselRef = new ActionReference();

  deselRef.putProperty( classChannel, keySelection );

  deselArgs.putReference( keyNull, deselRef );

  deselArgs.putEnumerated( keyTo, typeOrdinal, enumNone );

  executeAction( eventSet, deselArgs );

  app.preferences.rulerUnits = saveUnits;

};

Votes

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
Enthusiast ,
Jun 11, 2017 Jun 11, 2017

Copy link to clipboard

Copied

c.pfaffenbichler: wow... that's interesting. I prepared raw AM code for better understaning what's going on and better reusability.

var args = new ActionDescriptor();

var quadRect = new ActionList();

//original left top

quadRect.putUnitDouble(charIDToTypeID('#Pxl'),0);

quadRect.putUnitDouble(charIDToTypeID('#Pxl'),0);

//original right bottom

quadRect.putUnitDouble(charIDToTypeID('#Pxl'),20);

quadRect.putUnitDouble(charIDToTypeID('#Pxl'),20);

//new corners

var quadCorners = new ActionList();

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 0 ); //left top

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 0 );

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 20 ); //right top

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 0 );

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 20 ); //right bottom

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 20 );

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 0 ); //left bottom

quadCorners.putUnitDouble( charIDToTypeID('#Pxl'), 20 );

args.putList( stringIDToTypeID("rectangle"), quadRect );

args.putList( stringIDToTypeID("quadrilateral"), quadCorners );

executeAction( charIDToTypeID('Trnf'), args );

Votes

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
Enthusiast ,
Jun 11, 2017 Jun 11, 2017

Copy link to clipboard

Copied

c.pfaffenbichler: if I understand correctly this method should transform any rectangle into any quadrilateral (Quadrilateral)

But it doesn't seem to be designed for non-rectangular shape on input. It seems to be possible but a bit harder.

Votes

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
Community Expert ,
Jun 11, 2017 Jun 11, 2017

Copy link to clipboard

Copied

if I understand correctly this method should transform any rectangle into any quadrilateral

Alas, if it is run on a Smart Object that already has a transformation applied the result seems to be nonsensical.

Votes

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
Enthusiast ,
Jun 12, 2017 Jun 12, 2017

Copy link to clipboard

Copied

yes, but if you wrap SO into group you can show group-layer bounds and transform group. And you should see blue rectangle which will be input rectangle. I don't know why but SO sometimes has zero pixels after transformation. But it works with wraping SO into folder. I think undeforming should be possible with some math. And you also can read corner rectangles of SO.

Votes

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
Enthusiast ,
Jun 13, 2017 Jun 13, 2017

Copy link to clipboard

Copied

Seems to that I will be able improve "Undeform" script. Now always right bottom corner has wrong position.

And with quadrilateral transformation I am able change this corner and turn smart object into pixel perfect rectangle.

First I need find point where is intercept bottom edge of wrapper bounds and right edge of SO.

Then I need to find "q" for multiplication this "x" coordinate of intersection which will be equal to right top "x"

And similar for "y" axis.

More simple is apply one transformation for each axis.

You also can create new empty layer and link this layer with SO and then transform new empty layer. It works same as with group but you can avoid destroing of clipped layers and max group nesting limit

Votes

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
Community Expert ,
Jun 13, 2017 Jun 13, 2017

Copy link to clipboard

Copied

LATEST

Just to make sure credit is not misplaced: That function and the supporting parts are from »stacksupport.jsx« and »terminology.jsx«, I did not think them up myself but they are part of the Photoshop default Scripts.

And that I figured out how to utilise it in a custom Script was lucky …

Votes

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