Photoshop 脚本从文档的每一面裁剪 x 像素
Photoshop scripting crop away x pixels from every side of document
我有很多像这样的图片需要批量处理:
我想要完成的是剪掉每一边的边框,但这里有一个问题:修剪不起作用,因为图像每个角落的颜色都不是黑色而是白色,所以我改为'试图在每一侧裁掉大约 5 个像素。我已经写了一些代码来做到这一点,但似乎某处有错误导致有趣、镜像和错误裁剪的图像:
function cropLayerToBounds(){
var layer = activeDocument.activeLayer; //Grab the currently selected layer
// get height and width
var actualHeight = layer.bounds[2]-layer.bounds[0]; //Grab the height
var actualWidth = layer.bounds[3]-layer.bounds[1]; //Grab the width
// calculate desired height and width
var desiredHeight = actualHeight - 5;
var desiredWidth = actualWidth - 5;
// not sure if necessary
var doc = app.activeDocument;
var halfWidth = (desiredWidth/2);
var halfHeight = (desiredHeight/2);
var centerX = (doc.width/2);
var centerY = (doc.height/2);
// error seems to be here
// tried this
var bounds = [0,0,desiredHeight,desiredWidth];
// and this
var bounds = [(centerX-halfWidth),(centerY-halfHeight),(centerX+halfWidth),(centerY+halfHeight)];
doc.crop(bounds);
}
我用这种方式处理的图像看起来有点像这样:
以下脚本使用名为 cropCanvas
的自定义函数来满足您的要求。
没有必要访问 activeDocument.activeLayer
,因为裁剪会影响整个文档(即 canvas)。
示例要点:
var document = app.activeDocument; // Assumes a document is active.
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Crops the canvas by x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to crop.
*/
function cropCanvas(amountOfPixels) {
amountOfPixels = amountOfPixels || 0; // Defaults to zero.
// Obtain height and width of canvas.
var canvasWidth = document.width.value;
var canvasHeight = document.height.value;
// Define the new bounds.
var newBounds = [
amountOfPixels,
amountOfPixels,
canvasWidth - amountOfPixels,
canvasHeight - amountOfPixels
];
// Crop the canvas.
document.crop(newBounds);
}
// Invoke the `cropCanvas` function passing
// in the `amountOfPixels` value.
cropCanvas(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;
备注:
脚本最初通过 app.preferences.rulerUnits;
获取 Photoshop 的当前标尺单位,并将其分配给 originalRulerUnits
变量,然后再将标尺单位设置为像素。
cropCanvas(...)
函数有一个参数,即amountOfPixels
。这使得可以使用一个参数调用该函数,该参数指定裁剪图像所依据的像素数量。例如:
cropCanvas(5); // Crops 5 x pixels from all sides.
cropCanvas(25); // Crops 25 x pixels from all sides.
最后,Photoshop 的标尺单位被重置为其原始单位。
其他注意事项
不设置 app.preferences.rulerUnits = Units.PIXELS;
会导致根据您的问题中显示的示例进行不正确的裁剪。但是,当 Photoshop 的 标尺原点 的坐标 而不是 设置为 (0,0)
.
时,也会产生意想不到的结果
为了说明这个潜在的问题,请执行以下操作:
- 打开图像 PhotoShop。
- 通过键入 Command+R(macOS) 或 控制+R(Windows)
- 通过将 pointer/cursor 放置在 window 左上角的标尺交叉点上来更改标尺的零原点,然后沿对角线向下拖动到图像上。将出现一组十字线,标记标尺的新起点。进一步解释here
- 然后 运行 上面提供的示例要点。
如您所见,当标尺的零原点未设置为零时,可能会出现不希望的裁剪。
通过双击标尺的左上角,可以将标尺原点重置为默认值(即 0,0
)。
重要提示: 现在,正如您在问题中提到的那样,这对您来说应该不是什么大问题 "...需要作为批处理。",这表明您的最终脚本将以编程方式逐个打开图像(即自动化)。打开图像时,标尺原点默认为 0,0
,因此不会发生不需要的裁剪。
但是,在脚本的一个功能是允许它 运行 在用户打开的图像上并且可能已经定义了新的标尺原点的情况下。然后您的脚本还需要将标尺原点重置为零(即 0,0
)。
处理非零标尺原点的示例要点:
var document = app.activeDocument; // Assumes a document is active.
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Photoshop API doesn't provide a method to reset the ruler origin to [0, 0].
* This get the cuurent ruler origin so we can offset the value.
* @returns {Object} with properties `x` and `y` offset for rulers.
*/
function getRulerOffset() {
var ref = new ActionReference();
ref.putEnumerated(
charIDToTypeID("Dcmn"),
charIDToTypeID("Ordn"),
charIDToTypeID("Trgt")
);
var desc = executeActionGet(ref);
var rulerPositionX = desc.getInteger(stringIDToTypeID('rulerOriginH')) / 65536;
var rulerPositionY = desc.getInteger(stringIDToTypeID('rulerOriginV')) / 65536;
return {
x : rulerPositionX,
y : rulerPositionY
}
}
/**
* Crops the canvas by x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to crop.
*/
function cropCanvas(amountOfPixels) {
amountOfPixels = amountOfPixels || 0; // Defaults to zero.
// Obtain height and width of canvas.
var canvasWidth = document.width.value;
var canvasHeight = document.height.value;
// Obtain current ruler x and y offset.
var rulerOffsetX = getRulerOffset().x;
var rulerOffsetY = getRulerOffset().y;
// Define the new bounds.
var newBounds = [
amountOfPixels - rulerOffsetX,
amountOfPixels - rulerOffsetY,
canvasWidth - amountOfPixels - rulerOffsetX,
canvasHeight - amountOfPixels - rulerOffsetY
];
// Crop the canvas.
document.crop(newBounds);
}
// Invoke the `cropCanvas` function passing
// in the `amountOfPixels` value.
cropCanvas(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;
修改后的脚本(以上)现在除了以前的要点外还包括:
一个新函数,即getRulerOffset
,即returns当前x
和y
标尺原点的坐标。不幸的是,Photoshop 不提供可以调用以重置标尺原点的 API,因此我们必须获取当前值。
在cropCanvas
函数中,我们现在额外创建了两个新变量(rulerOffsetX
和rulerOffsetY
),并且在定义[=31时减去它们的值=]变量.
另一个利用resizeCanvas()
方法的解决方案
满足您要求的另一种方法是使用 resizeCanvas()
方法而不是 crop()
方法。我实际上更喜欢这种方法,因为 标尺原点 的位置(如 "Additional considerations" 部分所述)没有影响。
这里有一个要点:
var document = app.activeDocument;
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Resizes canvas removing x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to remove.
*/
function removePixelsFromAllSides(amountOfPixels) {
amountOfPixels = amountOfPixels || 0;
document.resizeCanvas(
document.width.value - (amountOfPixels * 2),
document.height.value - (amountOfPixels * 2),
AnchorPosition.MIDDLECENTER
);
}
// Invoke the function passing in the `amountOfPixels` value.
removePixelsFromAllSides(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;
我有很多像这样的图片需要批量处理:
我想要完成的是剪掉每一边的边框,但这里有一个问题:修剪不起作用,因为图像每个角落的颜色都不是黑色而是白色,所以我改为'试图在每一侧裁掉大约 5 个像素。我已经写了一些代码来做到这一点,但似乎某处有错误导致有趣、镜像和错误裁剪的图像:
function cropLayerToBounds(){
var layer = activeDocument.activeLayer; //Grab the currently selected layer
// get height and width
var actualHeight = layer.bounds[2]-layer.bounds[0]; //Grab the height
var actualWidth = layer.bounds[3]-layer.bounds[1]; //Grab the width
// calculate desired height and width
var desiredHeight = actualHeight - 5;
var desiredWidth = actualWidth - 5;
// not sure if necessary
var doc = app.activeDocument;
var halfWidth = (desiredWidth/2);
var halfHeight = (desiredHeight/2);
var centerX = (doc.width/2);
var centerY = (doc.height/2);
// error seems to be here
// tried this
var bounds = [0,0,desiredHeight,desiredWidth];
// and this
var bounds = [(centerX-halfWidth),(centerY-halfHeight),(centerX+halfWidth),(centerY+halfHeight)];
doc.crop(bounds);
}
我用这种方式处理的图像看起来有点像这样:
以下脚本使用名为 cropCanvas
的自定义函数来满足您的要求。
没有必要访问 activeDocument.activeLayer
,因为裁剪会影响整个文档(即 canvas)。
示例要点:
var document = app.activeDocument; // Assumes a document is active.
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Crops the canvas by x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to crop.
*/
function cropCanvas(amountOfPixels) {
amountOfPixels = amountOfPixels || 0; // Defaults to zero.
// Obtain height and width of canvas.
var canvasWidth = document.width.value;
var canvasHeight = document.height.value;
// Define the new bounds.
var newBounds = [
amountOfPixels,
amountOfPixels,
canvasWidth - amountOfPixels,
canvasHeight - amountOfPixels
];
// Crop the canvas.
document.crop(newBounds);
}
// Invoke the `cropCanvas` function passing
// in the `amountOfPixels` value.
cropCanvas(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;
备注:
脚本最初通过
app.preferences.rulerUnits;
获取 Photoshop 的当前标尺单位,并将其分配给originalRulerUnits
变量,然后再将标尺单位设置为像素。cropCanvas(...)
函数有一个参数,即amountOfPixels
。这使得可以使用一个参数调用该函数,该参数指定裁剪图像所依据的像素数量。例如:cropCanvas(5); // Crops 5 x pixels from all sides. cropCanvas(25); // Crops 25 x pixels from all sides.
最后,Photoshop 的标尺单位被重置为其原始单位。
其他注意事项
不设置 app.preferences.rulerUnits = Units.PIXELS;
会导致根据您的问题中显示的示例进行不正确的裁剪。但是,当 Photoshop 的 标尺原点 的坐标 而不是 设置为 (0,0)
.
为了说明这个潜在的问题,请执行以下操作:
- 打开图像 PhotoShop。
- 通过键入 Command+R(macOS) 或 控制+R(Windows)
- 通过将 pointer/cursor 放置在 window 左上角的标尺交叉点上来更改标尺的零原点,然后沿对角线向下拖动到图像上。将出现一组十字线,标记标尺的新起点。进一步解释here
- 然后 运行 上面提供的示例要点。
如您所见,当标尺的零原点未设置为零时,可能会出现不希望的裁剪。
通过双击标尺的左上角,可以将标尺原点重置为默认值(即 0,0
)。
重要提示: 现在,正如您在问题中提到的那样,这对您来说应该不是什么大问题 "...需要作为批处理。",这表明您的最终脚本将以编程方式逐个打开图像(即自动化)。打开图像时,标尺原点默认为 0,0
,因此不会发生不需要的裁剪。
但是,在脚本的一个功能是允许它 运行 在用户打开的图像上并且可能已经定义了新的标尺原点的情况下。然后您的脚本还需要将标尺原点重置为零(即 0,0
)。
处理非零标尺原点的示例要点:
var document = app.activeDocument; // Assumes a document is active.
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Photoshop API doesn't provide a method to reset the ruler origin to [0, 0].
* This get the cuurent ruler origin so we can offset the value.
* @returns {Object} with properties `x` and `y` offset for rulers.
*/
function getRulerOffset() {
var ref = new ActionReference();
ref.putEnumerated(
charIDToTypeID("Dcmn"),
charIDToTypeID("Ordn"),
charIDToTypeID("Trgt")
);
var desc = executeActionGet(ref);
var rulerPositionX = desc.getInteger(stringIDToTypeID('rulerOriginH')) / 65536;
var rulerPositionY = desc.getInteger(stringIDToTypeID('rulerOriginV')) / 65536;
return {
x : rulerPositionX,
y : rulerPositionY
}
}
/**
* Crops the canvas by x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to crop.
*/
function cropCanvas(amountOfPixels) {
amountOfPixels = amountOfPixels || 0; // Defaults to zero.
// Obtain height and width of canvas.
var canvasWidth = document.width.value;
var canvasHeight = document.height.value;
// Obtain current ruler x and y offset.
var rulerOffsetX = getRulerOffset().x;
var rulerOffsetY = getRulerOffset().y;
// Define the new bounds.
var newBounds = [
amountOfPixels - rulerOffsetX,
amountOfPixels - rulerOffsetY,
canvasWidth - amountOfPixels - rulerOffsetX,
canvasHeight - amountOfPixels - rulerOffsetY
];
// Crop the canvas.
document.crop(newBounds);
}
// Invoke the `cropCanvas` function passing
// in the `amountOfPixels` value.
cropCanvas(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;
修改后的脚本(以上)现在除了以前的要点外还包括:
一个新函数,即
getRulerOffset
,即returns当前x
和y
标尺原点的坐标。不幸的是,Photoshop 不提供可以调用以重置标尺原点的 API,因此我们必须获取当前值。在
cropCanvas
函数中,我们现在额外创建了两个新变量(rulerOffsetX
和rulerOffsetY
),并且在定义[=31时减去它们的值=]变量.
另一个利用resizeCanvas()
方法的解决方案
满足您要求的另一种方法是使用 resizeCanvas()
方法而不是 crop()
方法。我实际上更喜欢这种方法,因为 标尺原点 的位置(如 "Additional considerations" 部分所述)没有影响。
这里有一个要点:
var document = app.activeDocument;
// Obtain original ruler units prefs.
var originalRulerUnits = app.preferences.rulerUnits;
// Set the ruler units prefs to pixels.
app.preferences.rulerUnits = Units.PIXELS;
/**
* Resizes canvas removing x number of pixels equally from all sides.
* @param {Number} [amountOfPixels=0] - Number of pixels to remove.
*/
function removePixelsFromAllSides(amountOfPixels) {
amountOfPixels = amountOfPixels || 0;
document.resizeCanvas(
document.width.value - (amountOfPixels * 2),
document.height.value - (amountOfPixels * 2),
AnchorPosition.MIDDLECENTER
);
}
// Invoke the function passing in the `amountOfPixels` value.
removePixelsFromAllSides(5);
// Reset ruler prefs.
app.preferences.rulerUnits = originalRulerUnits;