Photoshop 脚本从文档的每一侧裁剪 x 像素

亚历克斯·高格尔

我有很多像这样的图像需要批量处理:

未处理的图像

我想要完成的是裁剪每一边的边框,但这里有一个问题:修剪不起作用,因为图像每个角落的颜色不是黑色而是白色,所以我试图裁剪每边大约 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将满足您的要求。

It's not necessary to access the activeDocument.activeLayer, as cropping affects the whole document (i.e. canvas).

Example gist:

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;

Notes:

  1. The script initially obtains Photoshop's current ruler units via app.preferences.rulerUnits; and assigns it to the originalRulerUnits variable, before setting the ruler units to pixels.

  2. The cropCanvas(...) function has one parameter, namely amountOfPixels. This enables the function to be invoked with one argument specifying the amount of pixels to crop the image by. For example:

    cropCanvas(5); // Crops 5 x pixels from all sides.
    
    cropCanvas(25); // Crops 25 x pixels from all sides.
    
  3. Finally, Photoshop's ruler units are reset to its original unit.


Additional considerations

By not setting app.preferences.rulerUnits = Units.PIXELS; can result in incorrect cropping as per the example shown in your question. However, Photoshop's ruler origin can also produce unexpected results too when it's coordinates are not set to (0,0).

To illustrate this potential issue carry out the following:

  1. Open an image PhotoShop.
  2. Show the rulers by typing Command+R(macOS), or Control+R(Windows)
  3. Change the ruler’s zero origin by positioning the pointer/cursor over the intersection of the rulers in the upper-left corner of the window, and drag diagonally down onto the image. A set of cross hairs will appear, marking the new origin for the rulers. Further explained here
  4. Then run the example gist provided above.

As you can see, when the ruler's zero origin is not set to zero, undesired cropping can occur.

The ruler origin can be reset to the default value, (i.e. 0,0), by double-clicking the upper-left corner of the rulers.

Important: Now, this should not be too much of an issue for you as you mention in your question "...need to be processed as a batch.", which suggests your final script will be opening images one-by-one programmatically (i.e. automated). When images are opened the ruler origin defaults to 0,0 so no undesired cropping should occur.

However, in a scenario whereby a feature of your script is to allow it to be run on an image which a user has opened and may have defined a new ruler origin. Then your script will also need to reset the ruler origin to zero (i.e. 0,0).

Example gist for handling non-zero ruler origin:

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;

The revised script (above) now includes in addition to the previous gist:

  1. A new function, namely getRulerOffset, that returns the current x and y coordinates of the ruler origin. Unfortunately, Photoshop does not provide an API which can be called to reset the ruler origin so we have to obtain the current values instead.

  2. In the cropCanvas function we now additionally create two new variables (rulerOffsetX and rulerOffsetY), and their values are subtracted when defining the newBounds variable.


利用该resizeCanvas()方法的另一种解决方案

满足您的要求的另一种方法是使用resizeCanvas()方法而不是crop()方法。我实际上更喜欢这种方法,因为标尺原点的位置(如“其他注意事项”部分所述)没有影响。

这是一个要点:

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;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章