Need Help: Programmatically Applying Free Transform Based on JSON Data in Photoshop Script
Hello Adobe Community,
I am working on a Photoshop script that aims to automate the process of creating layers and adjusting their shapes based on coordinates defined in a JSON file. My script is currently able to generate new layers and draw rectangle shapes according to source coordinates (srcquad) provided in the JSON. The next step, where I'm seeking assistance, involves transforming these newly created layers to align with destination coordinates (dstquad), also specified in the JSON file. This transformation might require moving and distorting the layer to fit the new coordinates.
The specific function I'm working with is createLayerAndRectangle(sourceLayer, layerName, srcquad, dstquad). It successfully creates a layer and shapes based on the srcquad. My objective is to apply a free transform to the new layer to match the dstquad coordinates.
Here's an excerpt from my script:
#target photoshop
#include "JsonPlugins/json2.js"
app.bringToFront();
// 创建窗口对象
var win = new Window("dialog", "JSON File Selector");
win.orientation = "column";
win.alignChildren = "fill";
win.add("statictext", undefined, "Select JSON File:");
var inputGroup = win.add("group");
inputGroup.orientation = "row";
inputGroup.alignChildren = "center";
var jsonInput = inputGroup.add("edittext", undefined, "");
jsonInput.characters = 35;
var browseButton = inputGroup.add("button", undefined, "Browse...");
browseButton.onClick = function() {
var file = File.openDialog("Select a JSON file", "*.json", false);
if (file) jsonInput.text = file.fsName;
};
var buttonGroup = win.add("group");
buttonGroup.orientation = "row";
buttonGroup.alignChildren = "center";
var progressPanel = win.add("panel", undefined, "Progress");
progressPanel.alignChildren = "fill";
var progressBar = progressPanel.add("progressbar", undefined, 0, 100);
progressBar.preferredSize.width = 300;
var cancelRequested = false;
var cancelButton = progressPanel.add("button", undefined, "Cancel");
cancelButton.onClick = function() {
cancelRequested = true;
};
var okButton = buttonGroup.add("button", undefined, "OK");
okButton.onClick = function() {
var jsonFile = File(jsonInput.text);
if (jsonFile.exists) {
jsonFile.open('r');
var jsonData = JSON.parse(jsonFile.read());
jsonFile.close();
progressBar.maxvalue = jsonData.length;
progressBar.value = 0;
var doc = app.activeDocument;
var sourcelayer = doc.layers[0];
var testForMax = 10; // 我们测试20张图片防止过过
for (var i = 2; i < jsonData.length; i++) {
var obj = jsonData[i];
try {
if(i >= testForMax)
break;
createLayerAndRectangle(sourcelayer,"Layer " + (obj.hashId || i + 1), obj.srcquad,obj.desquad);
} catch (error) {
alert("Error processing object at index " + i + ": " + error.message);
break; // Exit the loop if an error occurs
}
progressBar.value = i + 1;
}
alert("Process completed with " + i + " objects processed successfully.");
} else {
alert("JSON file does not exist.");
}
};
var closeButton = buttonGroup.add("button", undefined, "Close");
closeButton.onClick = function() {
win.close();
};
function createLayerAndRectangle(sourceLayer, layerName, srcquad, dstquad) {
var doc = app.activeDocument;
doc.activeLayer = sourceLayer;
// source quad points
var topLeft = [srcquad[0].x, srcquad[0].y];
var topRight = [srcquad[3].x, srcquad[3].y];
var bottomRight = [srcquad[2].x, srcquad[2].y];
var bottomLeft = [srcquad[1].x, srcquad[1].y];
var shapeRef = [topLeft, topRight, bottomRight, bottomLeft, topLeft];
// dest quad points
var dstTopLeft = [dstquad[0].x, dstquad[0].y];
var dstTopRight = [dstquad[3].x, dstquad[3].y];
var dstBottomRight = [dstquad[2].x, dstquad[2].y];
var dstBottomLeft = [dstquad[1].x, dstquad[1].y];
if (topLeft == topRight && topRight == bottomLeft && bottomLeft == bottomRight) {
return;
}
doc.selection.select(shapeRef);
// copy to new layer
var idCpTL = charIDToTypeID("CpTL");
executeAction(idCpTL, undefined, DialogModes.NO);
// rename new layer
var newLayer = doc.activeLayer;
newLayer.name = layerName;
//todo : how to free transform to dest quad ?
}
win.center();
win.show();
When doing this process manually, I would use Ctrl + T to initiate a free transform, then, while holding Ctrl, drag the corners to the desired coordinates specified by dstquad. My question to the community is: How can I replicate this manual process of free transforming a layer to an arbitrary quadrilateral shape programmatically through scripting?
Is there a known method, or could anyone suggest a series of commands within the Photoshop scripting framework that could mimic holding Ctrl and dragging points to new positions as done in the manual process?
Any guidance, advice, or suggestions would be greatly appreciated as I navigate through scripting this solution. Thank you for your time and help!
