Answered
can you help me create a script to do that job. i thank you very much for that. it helps me a lot in my work
This one would transform a placed image according to a four-point path.



// works only if the path for the tv-screens is comprised of only four corner points without handles;
// transforms the selected layer according to the selected or topmost path in the paths panel;
// use it at your own risk;
// 2008, pfaffenbichler;
#target photoshop
var myDocument = app.activeDocument;
var aPath = selectedPath2015 ();
var originalUnits = app.preferences.rulerUnits;
myDocument.pathItems[0].select();
myDocument.pathItems[0].deselect();
myDocument.selection.deselect();
// switch units to pixels;
app.preferences.rulerUnits = Units.PIXELS;
// check path;
if (aPath == undefined) {var aPath = myDocument.pathItems[0]};
if (aPath != undefined) {
// confirm the path has 4 points;
if (aPath.subPathItems.length == 1 && myDocument.pathItems[0].subPathItems[0].pathPoints.length == 4) {
// get the horicontal and vertical coordinates in pixels;
var hor1 = Number(aPath.subPathItems[0].pathPoints[0].anchor[0]);
var hor2 = Number(aPath.subPathItems[0].pathPoints[1].anchor[0]);
var hor3 = Number(aPath.subPathItems[0].pathPoints[2].anchor[0]);
var hor4 = Number(aPath.subPathItems[0].pathPoints[3].anchor[0]);
var ver1 = Number(aPath.subPathItems[0].pathPoints[0].anchor[1]);
var ver2 = Number(aPath.subPathItems[0].pathPoints[1].anchor[1]);
var ver3 = Number(aPath.subPathItems[0].pathPoints[2].anchor[1]);
var ver4 = Number(aPath.subPathItems[0].pathPoints[3].anchor[1]);
// order the horicontal and vertical coordinates;
var horList = [hor1, hor2, hor3, hor4];
var verList = [ver1, ver2, ver3, ver4];
horList.sort(sortNumber);
verList.sort(sortNumber);
// check the horicontal value;
var leftPoints = new Array;
var rightPoints = new Array;
for (var k=0; k<aPath.subPathItems[0].pathPoints.length; k++) {
if (aPath.subPathItems[0].pathPoints[k].anchor[0] == horList[0]
|| aPath.subPathItems[0].pathPoints[k].anchor[0] == horList[1]) {
leftPoints = leftPoints.concat(aPath.subPathItems[0].pathPoints[k].anchor)
}
else {
rightPoints = rightPoints.concat(aPath.subPathItems[0].pathPoints[k].anchor)
}
};
// define the four cornerpoints;
if (leftPoints[1] <= leftPoints[3]) {
var aTopLeft = [leftPoints[0], leftPoints[1]]
var aBottomLeft = [leftPoints[2], leftPoints[3]];
}
else {
var aTopLeft = [leftPoints[2], leftPoints[3]]
var aBottomLeft = [leftPoints[0], leftPoints[1]];
};
if (rightPoints[1] <= rightPoints[3]) {
var aTopRight = [rightPoints[0], rightPoints[1]]
var aBottomRight = [rightPoints[2], rightPoints[3]];
}
else {
var aTopRight = [rightPoints[2], rightPoints[3]]
var aBottomRight = [rightPoints[0], rightPoints[1]];
};
// sort numbers, found at www.w3schools.com;
function sortNumber(a,b) {
return a - b;
};
//////////// transformation ////////////
// 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 );
}
//////////// the new corners ////////////
transformActiveLayer( [new TPoint(aTopLeft[0], aTopLeft[1]), new TPoint(aTopRight[0], aTopRight[1]), new TPoint(aBottomRight[0], aBottomRight[1]), new TPoint(aBottomLeft[0], aBottomLeft[1])]);
// 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 );
// setArgs.putReference( keyNull, chanArg );
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] ) );
// setArgs.putObject( keyTo, classRectangle, boundsDesc );
// executeAction( eventSet, setArgs );
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[i].fX );
quadCorners.putUnitDouble( unitPixels, newCorners[i].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;
}
// resets the preferences units;
app.preferences.rulerUnits = originalUnits
}
else {
alert ("the topmost path does not conform to the requirements, it either comprises of more than one path or does not have exactly four points")};
};
////// determine selected path, updated 09.2015 //////
function selectedPath2015 () {
try {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID("property"), stringIDToTypeID("targetPathIndex"));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var docDesc = executeActionGet(ref);
return app.activeDocument.pathItems[docDesc.getInteger(stringIDToTypeID("targetPathIndex"))]
}
catch (e) {return undefined}
};
Sign up
Already have an account? Login
To post, reply, or follow discussions, please sign in with your Adobe ID.
Sign inSign in to Adobe Community
To post, reply, or follow discussions, please sign in with your Adobe ID.
Sign inEnter your E-mail address. We'll send you an e-mail with instructions to reset your password.
