Copy link to clipboard
Copied
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();
myDocu
...
Copy link to clipboard
Copied
I have a code but it has too many steps, what I need is for it to fill the TV
(function () {
// Script variables
var abort;
var bounds;
var docMaster;
var mask;
var maskC;
var maskH;
var maskW;
var title = "Adobe Script Tutorial 8";
// Reusable UI variables
var g; // group
var p; // panel
var w; // window
// SETUP
if (!app.documents.length) {
alert("Open the master document", title, false);
return;
}
app.displayDialogs = DialogModes.NO;
app.preferences.rulerUnits = Units.PIXELS;
docMaster = app.activeDocument;
mask = docMaster.channels.getByName("mask");
docMaster.selection.load(mask);
bounds = docMaster.selection.bounds;
maskW = bounds[2] - bounds[0];
maskH = bounds[3] - bounds[1];
maskC = [bounds[0] + (maskW / 2), bounds[1] + (maskH / 2)];
function maskLayer() {
// Mask active layer using document selection.
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
desc1.putClass(charIDToTypeID("Nw "), charIDToTypeID("Chnl"));
ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Msk "));
desc1.putReference(charIDToTypeID("At "), ref1);
desc1.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("UsrM"), charIDToTypeID("RvlS"));
executeAction(charIDToTypeID("Mk "), desc1, DialogModes.NO);
}
function processFile(file) {
var doc;
var docWork;
var fileJpg;
var layer;
var layerC;
var layerH;
var layerW;
var saveOptions;
var scale;
var scaleH;
var scaleW;
docWork = docMaster.duplicate();
doc = app.open(file);
try {
progress.message(File.decode(doc.name));
// Do something with image here
app.activeDocument = doc;
doc.flatten();
// Resize image
scaleH = maskH / doc.height;
scaleW = maskW / doc.width;
scale = Math.max(scaleH, scaleW);
doc.resizeImage(doc.width * scale, doc.height * scale, null, ResampleMethod.BICUBICSHARPER);
// Copy image to work document.
layer = doc.layers[0].duplicate(docWork);
app.activeDocument = docWork;
docWork.activeLayer = layer;
// Resize image to fit in master mask.
bounds = layer.bounds;
layerW = bounds[2] - bounds[0];
layerH = bounds[3] - bounds[1];
layerC = [bounds[0] + (layerW / 2), bounds[1] + (layerH / 2)];
layer.translate(maskC[0] - layerC[0], maskC[1] - layerC[1]);
docWork.selection.load(mask);
maskLayer();
// Save JPG
fileJpg = new File(txtFolderOutput.text + "/" + doc.name.replace(/\.[^\.]*$/, "") + "-framed.jpg");
saveOptions = new JPEGSaveOptions();
saveOptions.embedColorProfile = true;
saveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
saveOptions.quality = 12;
docWork.saveAs(fileJpg, saveOptions);
progress.increment();
} finally {
doc.close(SaveOptions.DONOTSAVECHANGES);
docWork.close(SaveOptions.DONOTSAVECHANGES);
}
}
function progress(message) {
var b;
var t;
var w;
w = new Window("palette", "Progress", undefined, {
closeButton: false
});
t = w.add("statictext", undefined, message);
t.preferredSize = [450, -1];
b = w.add("progressbar");
b.preferredSize = [450, -1];
progress.close = function () {
w.close();
};
progress.increment = function () {
b.value++;
};
progress.message = function (message) {
t.text = message;
app.refresh();
};
progress.set = function (steps) {
b.value = 0;
b.minvalue = 0;
b.maxvalue = steps;
};
w.show();
app.refresh();
}
})();
Copy link to clipboard
Copied
Please explain the actual task.
Do you have to insert many screens into one (or several pictures), the same screen in multiple images, …?
Copy link to clipboard
Copied
only 1 image per screen. The important thing is that it can be stretched to fit the selection you create.
Copy link to clipboard
Copied
The transformation could be automated if you create a four-point-path instead of a Selection.
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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}
};
Copy link to clipboard
Copied
you are so good. it is amazing. it works very well. thank you very much. i think a lot of people will need it. have a nice day, i don't know how to thank you
Copy link to clipboard
Copied
You’re welcome.
You may be able to amend the Script to more closely meet your needs, for example by providing a file-selection-dialog (for placing an external image) instead of it working on an existing Smart Object.
Copy link to clipboard
Copied
i am adding some steps to fit my work i am doing. but the hardest part you have already helped me complete them. awesome, you are so good, i will try to be a part of you
Copy link to clipboard
Copied
Copy link to clipboard
Copied
No, the Path has to have exactly four points to make the intended transformation unequivocally clear.
How did you create the Path? Can you provide the file with the path?