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

Transform Skew by mouse vs by typing exact value

Community Beginner ,
Mar 22, 2024 Mar 22, 2024

Copy link to clipboard

Copied

Hello,
I attached a video with the details.

I've done a skew on 2 selected objects by mouse dragging, but I want to get the same result by typing an exact value (number) rather than using the mouse drag. Because it's hard to drag the mouse to an exact whole number, so I want to make it by typing a value as a number, not dragging. The problem is when I type a number, it does the skew but only to one side (I want to bring 2 corners closer to each other). But with typing it only skew the whole thing to only one side, which is not what I want.

Best,

Adam

TOPICS
Windows

Views

488

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 Expert ,
Mar 27, 2024 Mar 27, 2024

Copy link to clipboard

Copied

You are right. I also tried with perspective wich does not require any shortcut and the problem remains the same. Changing the angle value only affect one of the rectangles…

Hope somebody will find a trick. But this meust be reported to the Photoshop team not as a bug but a deficient functionality that they could consider to enhance…

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 ,
Mar 27, 2024 Mar 27, 2024

Copy link to clipboard

Copied

The difference in your result seems to be the keyboard shortcuts you are adding. What exactly is Control-Alt-Shift doing to the image? Is the Alt key making both sides move and the Shift Key constraining it? If so, then this is what we need to duplicate when typing in a number.

Michelle

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 Beginner ,
Mar 29, 2024 Mar 29, 2024

Copy link to clipboard

Copied

"the Alt key making both sides move and the Shift Key constraining it"
I think so.
"this is what we need to duplicate when typing in a number."
What do you mean by that? I can make it by using the CTRL+SHIFT+ALT+MouseDrag, but I can't reach the same result by typing in a number for both sides. That's the problem. By MouseDrag it takes 1 sec to drag the 2 sides at the same time but it's painful to drag the mouse to the exact value. (almost impossible to drag the exact number I want). But I can't type in a number for both 2 sides to make the same result. You mean make a copy of one side of the object and then mirror it or rotate it? I think that's not how I want to make 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
Community Expert ,
Mar 31, 2024 Mar 31, 2024

Copy link to clipboard

Copied

quote

The difference in your result seems to be the keyboard shortcuts you are adding. What exactly is Control-Alt-Shift doing to the image?

By @mglush

 

It’s a combination of the common shortcuts which work across transformation types, when dragging a handle of the transform bounding box.

Option/Alt = Transform from center

Shift = Transform proportionally

Command = Warp only one corner of the bounding box

 

Command+Option = Skew

Command+Option+Shift = These modifier keys seem to achieve the same thing as Edit > Transform > Perspective.

 

That last one seems to be the problem here:

The thread title talks about skewing, but the video does not show skewing. The result shown in the video is the same as Edit > Transform > Perspective, not Edit > Transform > Skew. But the options bar is not showing perspective values, it shows skew values. So changing a skew value will not achieve a perspective result.

 

It doesn’t look like the options bar offers a perspective setting. The options bar doesn’t even offer a perspective value after choosing Edit > Transform > Perspective!

 

So there may not be a way to apply perspective using the options bar, but I hope I’m wrong.

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 Beginner ,
Apr 01, 2024 Apr 01, 2024

Copy link to clipboard

Copied

"the options bar is not showing perspective values, it shows skew values"
Yeah, you're probably right. But I can't modify the question's title from skew to perspective. Since Photoshop showed me skewing options at the bar, I couldn't decide if it's the skew or persp menu actually...

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 ,
Apr 01, 2024 Apr 01, 2024

Copy link to clipboard

Copied

quote

Since Photoshop showed me skewing options at the bar, I couldn't decide if it's the skew or persp menu actually...

By @adam2287631

 

Yeah, that's not your fault, when the Perspective command is chosen there should be a Perspective field up there. And it would also be nice to have a Perspective field in the options bar when the Free Transform command was chosen. This area could use some refinement and clarification for sure.

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 ,
Mar 28, 2024 Mar 28, 2024

Copy link to clipboard

Copied

By virtue of the keyboard shortcut you are using you are not skewing. 

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 Beginner ,
Mar 29, 2024 Mar 29, 2024

Copy link to clipboard

Copied

Ok. Thanks. So what is the answer to my question?

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 ,
Mar 29, 2024 Mar 29, 2024

Copy link to clipboard

Copied

That you haven’t been using the term »skew« correctly? 

 

If you want to be able to give numerical input for perspectival transformation in Photoshop you would need to use a Script as far as I can tell. 

Which seems perfectly possible (for a first transformation at least, if the object is a Smart Object that has already been transformed the issue gets »murky«), but which kind of input makes the most sense in your use-case? 

An angle or a distance for the two corners or the percentage of the width in relation to the original width or …? 

 

Please provide sample files for original and intended result. 

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 ,
Mar 29, 2024 Mar 29, 2024

Copy link to clipboard

Copied

Great question. Would a script work better than an action?

Michelle

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 ,
Mar 31, 2024 Mar 31, 2024

Copy link to clipboard

Copied

A Script could take numerical input. 

 

Perspectival transformation of multiple Layers seems difficult to Script though. 

So the easiest way would be converting the two to one Smart Object. 

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 ,
Apr 01, 2024 Apr 01, 2024

Copy link to clipboard

Copied

The following Script would convert multiple selected Layers to a Smart Object and offset the top left and right corners by x pixels. 

Screenshot 2024-04-01 at 14.10.54.pngScreenshot 2024-04-01 at 14.12.39.png

// 2024, use it at your own risk;
if (app.documents.length > 0) {
var theDist = prompt("please enter value to move the upper corners towards each other:");
if (theDist != undefined) {
var theDist = Number (theDist);
// set to pixels;
//executeAction( stringIDToTypeID( "revert" ), undefined, DialogModes.NO );
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var selectedLayers = collectSelectedLayersBounds ();
// convert to smart object if more than one;
if (selectedLayers.length > 1) {
var theSO = convertToSmartObject ();
var theBounds = theSO[2];
} else {
// if smart object;
if (isSmartObject() == true) {var theBounds = selectedLayers[0][2]}
// if one layer but not smart object;
else {
var theSO = convertToSmartObject ();
var theBounds = theSO[2]
};
};
transformByCornerpoints ([theBounds[0]+theDist, theBounds[1]], [theBounds[2]-theDist, theBounds[1]], [theBounds[2], theBounds[3]], [theBounds[0], theBounds[3]])
// reset;
app.preferences.rulerUnits = originalRulerUnits;
};
};
////// collect bounds of selected layers //////
function collectSelectedLayersBounds () {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
// get selected layers;
var selectedLayers = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
if (desc.getBoolean(stringIDToTypeID("hasBackgroundLayer")) == true) {var theAdd =0}
else {var theAdd = 1};
if( desc.hasKey( stringIDToTypeID( 'targetLayers' ) ) ){
desc = desc.getList( stringIDToTypeID( 'targetLayers' ));
var c = desc.count;
var selectedLayers = new Array();
// run through selected layers;
for(var i=0;i<c;i++){
var theIndex = desc.getReference( i ).getIndex()+theAdd;
// get id for solid color layers;
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID("Lyr "), theIndex ); 
var layerDesc = executeActionGet(ref);
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
selectedLayers.push([theName, theIdentifier, theseBounds]);
} catch (e) {};
};
// if only one:
}else{
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
try {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theIdentifier = layerDesc.getInteger(stringIDToTypeID ("layerID"));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
selectedLayers = [[theName, theIdentifier, theseBounds]]
} catch (e) {};
};
// reset;
app.preferences.rulerUnits = originalRulerUnits;
return selectedLayers;
};
////// transform by corner points //////
function transformByCornerpoints (aTopLeft, aTopRight, aBottomRight, aBottomLeft) {
//////////// transformation ////////////
// from adobe’s terminology.jsx;
const classChannel = app.charIDToTypeID('Chnl');
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] ) );
//	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;
}
};
////// convert to smart object //////
function convertToSmartObject () {
var desc108 = new ActionDescriptor();
var ref77 = new ActionReference();
ref77.putEnumerated( charIDToTypeID( "Mn  " ), charIDToTypeID( "MnIt" ), stringIDToTypeID( "newPlacedLayer" ) );
desc108.putReference( charIDToTypeID( "null" ), ref77 );
executeAction( charIDToTypeID( "slct" ), desc108, DialogModes.NO );
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var layerDesc = executeActionGet(ref);
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
var theWidth = theseBounds[2]-theseBounds[0];
var theHeight = theseBounds[3]-theseBounds[1];
return [theName, theID, theseBounds, theWidth, theHeight]
};
////// is smart object //////
function isSmartObject () {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("smartObject"));
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var layerDesc = executeActionGet(ref);
var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
return isSmartObject
};

 

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 Beginner ,
Apr 01, 2024 Apr 01, 2024

Copy link to clipboard

Copied

I don't know if your code works, but good idea. They should integrate something like this into Photoshop too.

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 ,
Apr 01, 2024 Apr 01, 2024

Copy link to clipboard

Copied

quote

I don't know if your code works, 

Then please test it. 

Edit: Save the code as a txt-file, change the extension to .jsx and copy it into Photoshop’s Presets/Scripts-Folder; after restarting Photoshop it should be available under File > Scripts and can be assigned a Shortcut or used in an Action. 

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

LATEST

@adam2287631 , have you been able to test the Script? 

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 ,
Mar 29, 2024 Mar 29, 2024

Copy link to clipboard

Copied

FWIIW I almost never use the Free Transform settings.  I Ctrl drag a corner handle to distort

image.png

Ctrl drag a middle handle to skew

image.png

The only time I use the X: and Y: field values is for the centre handle, like when using Step & Repeat

Unfortunately, the outside handles wont snap to guides or the grid.

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 ,
Apr 02, 2024 Apr 02, 2024

Copy link to clipboard

Copied

Come to think of it … 

Transforming multiple Layers via Script works out easier by grouping them and evaluating the »boundsNoEffects«. 

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