Copy link to clipboard
Copied
Hi guys, I know almost anything is possible with scripting but im a total newb, id normally set up an action for something like this, but I don't think actions have this level of control. any help please please please
it would run something like,
1. Select Layer
2. Crop Layer to Size
3. Re-size canvas to nearest multiple of 12, in pixels. Expanded from the top left to preserve the coordinate.
4. Save
Copy link to clipboard
Copied
// Crop layer by bounds multiple 12
var lyrs = getSelectedLayersInfo(),
mult = 12,
_top = lyrs[0].top,
_right = (Math.ceil((lyrs[0].width / mult)) * mult) + lyrs[0].left,
_bottom = (Math.ceil((lyrs[0].height / mult)) * mult) + lyrs[0].top,
_left = lyrs[0].left;
crop(_top, _right, _bottom, _left);
function crop(_top, _right, _bottom, _left) {
var desc1 = new ActionDescriptor();
var desc2 = new ActionDescriptor();
desc2.putUnitDouble(charIDToTypeID('Top '), charIDToTypeID('#Pxl'), _top);
desc2.putUnitDouble(charIDToTypeID('Left'), charIDToTypeID('#Pxl'), _left);
desc2.putUnitDouble(charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), _bottom);
desc2.putUnitDouble(charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), _right);
desc1.putObject(charIDToTypeID('T '), charIDToTypeID('Rctn'), desc2);
desc1.putUnitDouble(charIDToTypeID('Angl'), charIDToTypeID('#Ang'), 0);
desc1.putBoolean(charIDToTypeID('Dlt '), false);
desc1.putEnumerated(stringIDToTypeID("cropAspectRatioModeKey"), stringIDToTypeID("cropAspectRatioModeClass"), stringIDToTypeID("pureAspectRatio"));
desc1.putBoolean(charIDToTypeID('CnsP'), false);
executeAction(charIDToTypeID('Crop'), desc1, DialogModes.NO);
}
function getSelectedLayersInfo() {
try {
var lyrs = [];
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));
var targetLayers = executeActionGet(ref).getList(stringIDToTypeID("targetLayers"));
for (var i = 0; i < targetLayers.count; i++) {
var lyr = new Object();
var ref2 = new ActionReference();
try {
activeDocument.backgroundLayer;
ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex());
lyr.index = executeActionGet(ref2).getInteger(stringIDToTypeID("itemIndex")) - 1;
} catch (o) {
ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex() + 1);
lyr.index = executeActionGet(ref2).getInteger(stringIDToTypeID("itemIndex"));
}
lyr.layerSection = typeIDToStringID(executeActionGet(ref2).getEnumerationValue(stringIDToTypeID('layerSection')));
if (lyr.layerSection != "layerSectionStart") {
try {
var bounds = executeActionGet(ref2).getObjectValue(stringIDToTypeID("boundsNoEffects"));
} catch (o) {
var bounds = executeActionGet(ref2).getObjectValue(stringIDToTypeID("bounds"));
}
lyr.top = bounds.getDouble(stringIDToTypeID("top"));
lyr.right = bounds.getDouble(stringIDToTypeID("right"));
lyr.bottom = bounds.getDouble(stringIDToTypeID("bottom"));
lyr.left = bounds.getDouble(stringIDToTypeID("left"));
try {
lyr.width = bounds.getDouble(stringIDToTypeID("width"));
lyr.height = bounds.getDouble(stringIDToTypeID("height"));
} catch (e) {
lyr.width = bounds.getDouble(stringIDToTypeID("right")) - bounds.getDouble(stringIDToTypeID("left"));
lyr.height = bounds.getDouble(stringIDToTypeID("bottom")) - bounds.getDouble(stringIDToTypeID("top"));
}
} else {
var _ff = getRealFolderSizeByIndex(lyr.index);
lyr.top = _ff[0];
lyr.left = _ff[1];
lyr.bottom = _ff[2];
lyr.right = _ff[3];
lyr.width = _ff[4];
lyr.height = _ff[5];
}
lyrs.push(lyr);
}
return lyrs
} catch (e) {}
}
function getRealFolderSizeByIndex(idx) {
try {
var nestedSets = 0,
lyrs = [];
for (var l = idx - 1; l > 0; l--) {
var layerSection = getLayerSectionByAMIndex(l);
if (layerSection[0] == 'layerSectionContent' && layerSection[1] == false) lyrs.push(getLayerBoundsByIndex(l));
if (layerSection[0] == 'layerSectionStart') nestedSets++;
if (layerSection[0] == 'layerSectionEnd' && nestedSets <= 0) return calc(lyrs);
if (layerSection[0] == 'layerSectionEnd' && nestedSets > 0) nestedSets--;
}
function getLayerSectionByIndex(idx) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID("Lyr "), idx);
return [typeIDToStringID(executeActionGet(ref).getEnumerationValue(stringIDToTypeID('layerSection'))), executeActionGet(ref).getBoolean(charIDToTypeID('Grup'))];
}
function getLayerBoundsByIndex(index) {
var ref = new ActionReference();
ref.putIndex(charIDToTypeID('Lyr '), index);
var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID("bounds"));
var bounds = [];
for (var b = 0; b < 4; b++) {
bounds.push(desc.getUnitDoubleValue(desc.getKey(b)));
}
return bounds;
}
function calc(lyrs) {
var _f = [],
_t = [],
_b = [],
_l = [],
_r = [];
for (g in lyrs) {
_t.push(lyrs
[0]); _l.push(lyrs
[1]); _b.push(lyrs
[2]); _r.push(lyrs
[3]); }
_f.push(min(_t));
_f.push(min(_l));
_f.push(max(_b));
_f.push(max(_r));
_f.push(_f[3] - _f[1]);
_f.push(_f[2] - _f[0]);
return _f
}
} catch (e) {}
}
function max(list) {
var m = list[0];
for (var i = 1; i < list.length; i++) {
if (list > m) m = list;
}
return m;
}
function min(list) {
var m = list[0];
for (var i = 1; i < list.length; i++) {
if (list < m) m = list;
}
return m;
}
Copy link to clipboard
Copied
shaunr923725 wrote:
Hi guys, I know almost anything is possible with scripting but im a total newb, id normally set up an action for something like this, but I don't think actions have this level of control. any help please please please
it would run something like,
1. Select Layer
2. Crop Layer to Size
3. Re-size canvas to nearest multiple of 12, in pixels. Expanded from the top left to preserve the coordinate.
4. Save
While you can select a layer. You can not crop a single layer unless the document only has one layer. Crop is a whole document thing. All layer that have pixels outside the crop area would be cropped to the pixels within the crop area. If a layer select is not the Photoshop background layer you can resize the layer with transform. Or you can delete pixels around some area with an inverted selection of the area and a clear selection the remaining pixels would be like a layer being cropped. However the area can have any relation to the document canvas. It does not need to be centered over the canvas.
Resizing the canvas will crop or add colored in pixels to the Photoshop background layer for that is a special layer that does not support transparency. A background layer is always canvas size with no transparency at all. The document canvas size will act like a clipping mask for all other layer in a document. Layers can be any size.