@Mark37430984r9lw
You can try the following script. It's interactive, once you know what the average/common % margin values are, it is easy to update these values and turn off the interactive step so that this can be batched.
EDIT: I have updated the original interactive guide layout code to now work in % without manually setting the units.
The script will then crop to the guides and remove the guides. The cropped pixels can be retained or permanently deleted by changing false to true in the crop function call.
/*
Canvas Margin Percentage Crop.jsx
v1.2 - 12th June 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/i-want-to-make-a-form-to-define-crops/td-p/14675929
*/
#target photoshop
// Check if a document is open
if (app.documents.length > 0) {
// Set the document variable
var doc = app.activeDocument;
// Get and set the ruler units
var origRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PERCENT;
// Conditionally clear existing guides
if (app.activeDocument.guides.length > 0)
app.runMenuItem(stringIDToTypeID('clearGuides'));
// Change ALL to NO to disable interactivity when batching
var interactive = DialogModes.ALL;
// Add 4 margin guides based on % of canvas size
// Enter your desired values - top, left, bottom, right
newGuideLayout(10, 25, 10, 25);
// Set the rulers to pixels
app.preferences.rulerUnits = Units.PIXELS;
// Get the existing guides
var guides = getGuides(doc);
if (guides.horizontal.length >= 2 && guides.vertical.length >= 2) {
// Sort the guides to find the outermost guides
guides.horizontal.sort(function(a, b) { return a - b; });
guides.vertical.sort(function(a, b) { return a - b; });
// Define the selection region based on the outermost guides
var selectionRegion = [
[guides.vertical[0], guides.horizontal[0]], // Top-left
[guides.vertical[guides.vertical.length - 1], guides.horizontal[0]], // Top-right
[guides.vertical[guides.vertical.length - 1], guides.horizontal[guides.horizontal.length - 1]], // Bottom-right
[guides.vertical[0], guides.horizontal[guides.horizontal.length - 1]] // Bottom-left
];
// Make the selection
doc.selection.select(selectionRegion);
// Crop to the selection: delete cropped pixels = true
cropToSelection(doc.selection.bounds[1], doc.selection.bounds[0], doc.selection.bounds[3], doc.selection.bounds[2], false);
// Conditionally clear existing guides
if (app.activeDocument.guides.length > 0)
app.runMenuItem(stringIDToTypeID('clearGuides'));
// Reset the original ruler units
app.preferences.rulerUnits = origRulerUnits;
} else {
alert("Please make sure there are at least 2 horizontal and 2 vertical guides.");
}
} else {
alert("No document is open.");
}
// Functions
function getGuides(doc) {
var guides = doc.guides;
var horizontalGuides = [];
var verticalGuides = [];
for (var i = 0; i < guides.length; i++) {
if (guides[i].direction == Direction.HORIZONTAL) {
horizontalGuides.push(guides[i].coordinate.as('px'));
} else {
verticalGuides.push(guides[i].coordinate.as('px'));
}
}
return {horizontal: horizontalGuides, vertical: verticalGuides};
}
function newGuideLayout(marginTop, marginLeft, marginBottom, marginRight) {
app.preferences.rulerUnits = Units.PERCENT;
var c2t = function (s) {
return app.charIDToTypeID(s);
};
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
descriptor.putBoolean(s2t("replace"), true); // true or false boolean
descriptor.putEnumerated(s2t("presetKind"), s2t("presetKindType"), s2t("presetKindCustom"));
descriptor2.putUnitDouble(s2t("marginTop"), s2t("percentUnit"), marginTop);
descriptor2.putUnitDouble(s2t("marginLeft"), s2t("percentUnit"), marginLeft);
descriptor2.putUnitDouble(s2t("marginBottom"), s2t("percentUnit"), marginBottom);
descriptor2.putUnitDouble(s2t("marginRight"), s2t("percentUnit"), marginRight);
descriptor2.putInteger(c2t("GdCA"), 0); // ?
descriptor2.putInteger(c2t("GdCR"), 74); // Red value
descriptor2.putInteger(c2t("GdCG"), 255); // Green value
descriptor2.putInteger(c2t("GdCB"), 255); // Blue value
descriptor.putObject(s2t("guideLayout"), s2t("guideLayout"), descriptor2);
descriptor.putEnumerated(s2t("guideTarget"), s2t("guideTarget"), s2t("guideTargetCanvas"));
executeAction(s2t("newGuideLayout"), descriptor, interactive);
}
function cropToSelection(top, left, bottom, right, retainPixels) {
// Courtesy of Chuck Uebele
app.preferences.rulerUnits = Units.PIXELS;
var idCrop = charIDToTypeID("Crop");
var desc11 = new ActionDescriptor();
var idT = charIDToTypeID("T ");
var desc12 = new ActionDescriptor();
var idTop = charIDToTypeID("Top ");
var idPxl = charIDToTypeID("#Pxl");
desc12.putUnitDouble(idTop, idPxl, top);
var idLeft = charIDToTypeID("Left");
var idPxl = charIDToTypeID("#Pxl");
desc12.putUnitDouble(idLeft, idPxl, left);
var idBtom = charIDToTypeID("Btom");
var idPxl = charIDToTypeID("#Pxl");
desc12.putUnitDouble(idBtom, idPxl, bottom);
var idRght = charIDToTypeID("Rght");
var idPxl = charIDToTypeID("#Pxl");
desc12.putUnitDouble(idRght, idPxl, right);
var idRctn = charIDToTypeID("Rctn");
desc11.putObject(idT, idRctn, desc12);
var idAngl = charIDToTypeID("Angl");
var idAng = charIDToTypeID("#Ang");
desc11.putUnitDouble(idAngl, idAng, 0.000000);
var idDlt = charIDToTypeID("Dlt ");
desc11.putBoolean(idDlt, retainPixels); // delete cropped pixels = true | false
var idcropAspectRatioModeKey = stringIDToTypeID("cropAspectRatioModeKey");
var idcropAspectRatioModeClass = stringIDToTypeID("cropAspectRatioModeClass");
var idtargetSize = stringIDToTypeID("targetSize");
desc11.putEnumerated(idcropAspectRatioModeKey, idcropAspectRatioModeClass, idtargetSize);
executeAction(idCrop, desc11, DialogModes.NO);
}
https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html