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

Distort Smart Object inputing coordinates

Community Beginner ,
Jun 27, 2020 Jun 27, 2020

I've been searching the internet far and wide for a solution, basically I want a function to be able to distort a smart object using 4 coordinates (top left, top right, bottom left, bottom right).

Of course, I've looked into it a bit and it's not as easy as that, the following is the resulting code of dragging the top right corner of a smart object and it's something like this:

drag.png

 

// =======================================================
// Javascript ScriptListener Code Beautified with Clean SL
transform(-50.319489, -50.319489, 130.127796, 0, -25.38032, -0.080511, 0);
function transform(horizontal, vertical, height, horizontal2, vertical2, horizontal3, vertical3) {
	var c2t = function (s) {
		return app.charIDToTypeID(s);
	};

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

	var descriptor = new ActionDescriptor();
	var descriptor2 = new ActionDescriptor();
	var descriptor3 = new ActionDescriptor();
	var descriptor4 = new ActionDescriptor();

	descriptor.putEnumerated( s2t( "freeTransformCenterState" ), s2t( "quadCenterState" ), s2t( "QCSAverage" ));
	descriptor2.putUnitDouble( s2t( "horizontal" ), s2t( "pixelsUnit" ), horizontal );
	descriptor2.putUnitDouble( s2t( "vertical" ), s2t( "pixelsUnit" ), vertical );
	descriptor.putObject( s2t( "offset" ), s2t( "offset" ), descriptor2 );
	descriptor.putUnitDouble( s2t( "height" ), s2t( "percentUnit" ), height );
	descriptor3.putUnitDouble( s2t( "horizontal" ), s2t( "angleUnit" ), horizontal2 );
	descriptor3.putUnitDouble( s2t( "vertical" ), s2t( "angleUnit" ), vertical2 );
	descriptor.putObject( s2t( "skew" ), c2t( "Pnt " ), descriptor3 );
	descriptor4.putUnitDouble( s2t( "horizontal" ), s2t( "percentUnit" ), horizontal3 );
	descriptor4.putUnitDouble( s2t( "vertical" ), s2t( "percentUnit" ), vertical3 );
	descriptor.putObject( s2t( "using" ), c2t( "Pnt " ), descriptor4 );
	executeAction( s2t( "transform" ), descriptor, DialogModes.NO );
}

 

I just moved one corner straight up and 5/7 parameters are changed. I've no idea how to transform 4 coordinates into these 7 parameters.

There is a script named "Undeform 1.1", which lets you undo almost all kinds of transformations done to a smart object, I've tried looking into it to see if there was something I could use but I'm not very good with scripting.

I've found an alternative to this but it's not very good, basically, I can use an external program to move the mouse and drag the corners of the distort to the coordinates I want but it's not as good as a solution in the program itself.

TOPICS
Actions and scripting
1.5K
Translate
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

Community Expert , Jun 28, 2020 Jun 28, 2020

If you start with an untransformed Smart Object this might help. 

At current it uses a four-point-path but you can adapt the code to take an array of four points derived otherwise … 

Screenshot 2020-06-28 at 22.13.47.pngScreenshot 2020-06-28 at 22.13.59.png

 

// 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;
// 2019, pfaffenbichler;
#target photoshop
var myDocument = app.activeDocument;
var aPath = s
...
Translate
Adobe
Community Expert ,
Jun 28, 2020 Jun 28, 2020

Modifying a Smart Object Layer's transform would be very difficult I would think.  If you search this forum you should be able to find  code that r-bin posted that retrieves a Smart Objects Layer's current objects trams information. So you can get the layer's Objects current transform settings which can contain complex warping.  To distort the object to something in the document composite.  Like putting a rectangle label on a wine bottle. I have idea of how one would be able to change a smart object current distortion  and warp it the your distortion.  Morph the curved wine bottle label to a flat image surface and add the your perspective distortion.

 

A smart object layer transform and warp for  a card driver seat back. How would you transform and warp from the current one?

Capture.jpg

 

JJMack
Translate
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
Mentor ,
Jun 28, 2020 Jun 28, 2020

The problem is that control points are just a control element. Information about the transformation of the object is stored in a different form. Look at this topic, maybe it will help you:

 

https://community.adobe.com/t5/photoshop/get-layer-transform-x-y-top-left-coordinate-position/m-p/97...

Translate
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 28, 2020 Jun 28, 2020

Yes that the tread  I wrote about that I could not find. Where r-bin supplied the code for me to gets  current information about the smart object current tranformation.   How to use the Warping information is beyond my know how and, at my age I have no desire the learn how the information is used.

JJMack
Translate
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 28, 2020 Jun 28, 2020

If you start with an untransformed Smart Object this might help. 

At current it uses a four-point-path but you can adapt the code to take an array of four points derived otherwise … 

Screenshot 2020-06-28 at 22.13.47.pngScreenshot 2020-06-28 at 22.13.59.png

 

// 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;
// 2019, 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}
};

 

 

Translate
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 28, 2020 Jun 28, 2020

Yes I would think if you create the smart layer and create a particular way you can do what the op want to do.  However, you can not know how it will on a mockup template smart object layer that someone else crates you know not how. Using the code r-bin posted you may be able to determine if  there was warping added you can not handle. The seem two parts or three parts when it come to Transforming as smart object.  This Smart Object layer was create using Place to in as raw Image and I accept places default transform. The image was  not degraded by place for both document have a 300dpi print resolution.  However, place did scale the smart object layer to fit on canvas because my preference is resize during Place, You can see the Percent the image was scaled in the transform option bar.  So the layers bounds is way smaller then the actual object.  You can rectify that if you know there has been no warping done . You transform the layer to the Object's size width 100%  height 100%. It does  not matter if the image has or has not been degraded by place,  You get the object to its actual size.  I do this all the time in my collage scripts the transform the opbect the way I wan to fill an Alpha channel section then mask off the excess image,  I transform Placed object all the time for I know my  mys scripts do not warp images.  Place may scale and degrade the image I can stall get the object actuals size and transform for the object the ways I need to.

Capture.jpg

JJMack
Translate
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 Beginner ,
Jun 28, 2020 Jun 28, 2020

Yes, that's exactly it. I didn't explain it well but I'm using it for making mockups so I start with an untransformed rectangle.

I've tested the script and it works perfectly, I only need to tweak it a bit but it shouldn't be hard.

Thanks for the help, everyone.

Translate
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 28, 2020 Jun 28, 2020

How do you  know if a rectangle has not been  scaled or not scaled by the smart object layer's object transform.   I use a sledge hammer and transform the smart object layer to 100% wide  and 100% high to insure the object has not been scaled.  So I can get the object actual size and position relative to the document's  canvas, A placed image rectangle canvas has the same aspect ratio if the object has been scaled  or not scaled. The difference will be the layers corner x,y document position. The layers bounds bounds will be different. Which may or may not be within the document's  canvas bounds. If the object has also been warped I would not know hoe to transform the object the way  I want to transform it.  If you do not how the smart object layer was created  you need to find out how the object is currently being transformed. And act accordingly

JJMack
Translate
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 28, 2020 Jun 28, 2020

One of the first things a scripted was creating collages using Place. To place in Images in collages templates. Place drove me up the wall because of the way Adobe implemented it. IMO place has a real issued.  It should not degrade images based on  two document print pixel sizes. Place should work like copy paste, duplicate layer and drag and dropping layer between documents. Preserve an image's  pixels. Why Place interpolated image baffles me.  Drove me crazy why I got the results i wanted some times and not other times.  I did not expect place would degrade my image interpolation there sizes for print pixel sizes. I was creating composite collages  not print printing part of a composite.  IMO Place should not interpolate my image to a different size image. I want to use my images pixels not a scaled image scale to] a to  bad size choice. It dose not matter if Adobe scale an image up or down is size. Image quality s lost. If Adobe choose a small images side I'll loose all good image details when the scripts sized the object for the collages image location size and shape.  I know how to avoided this disaster. Change all image file involved to have the sames resolution  as the template file without sampling the images. Then place will not resize images place may scale a smart object layer if resize during place is checked  in one's preference to fit the layer onto the  documents canvas. The Image however will be you image  and the smart object pixels will be you images pixels.

JJMack
Translate
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 Beginner ,
Jun 28, 2020 Jun 28, 2020
LATEST

In my case I'm selecting a rectangle, filling it with a pattern and transforming it into a smart object so I can be sure it is not transformed.

However, for other cases, using Undeform 1.1 (by Jaroslav Bereza http://bereza.cz) you can reset an smart object to its original state (I don't know if it works perfectly but at least with warp, distort, skew, etc. it works well).

I also don't like the way place works with print pixel sizes, thankfully Layer / Duplicate Layer works well.

Translate
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