javascriptphotoshopphotoshop-script

Photoshop script calculation issue


The below code downsizes an image layer (which is the full width/height of the canvas) to allow for a border. The borderWidth is calculated based on a percentage of canvasHeight. The newWidth is original width minus borderWidth * 2. The newHeight is scaled according to the original canvas ratio.

eg. the image layer filling a canvas of 1000px width x 3000px height, with borderWidth of 150px (3000 x 0.05), would be scaled down to 700px width x 2100px height.

The problem is that the width is being reduced by a percentage of canvasWidth rather than a percentage of canvasHeight as specified.

I feel like this has something to do with setting the ruler units to PERCENT. However without doing this the resize command does not work.

I've tried setting both PERCENT and PIXELS in different areas of the script with no success.

I've also gone off on tangents thinking the way I was referencing the size was an issue, so I tried using layer.bounds to get the layer size rather than doc.width and doc.height. No difference.

I'm at a loss.

var doc = app.activeDocument;
var layer = doc.activeLayer;
app.preferences.rulerUnits = Units.PERCENT; 
var canvasWidth = doc.width;
var canvasHeight = doc.height;
var borderWidth = canvasHeight * 0.05;
var newWidth = canvasWidth - (2 * borderWidth);
var newHeight = newWidth * (canvasHeight/canvasWidth);

layer.resize(newWidth, newHeight, AnchorPosition.MIDDLECENTER);

Solution

  • If you look at the docs you'll see that layer resize is a percentage regardless of what the units are set at.

    So you need to calculate the scale percentage:

    var scalePercent = (newWidth/canvasWidth)*100;
    

    and then resize:

    layer.resize(scalePercent, scalePercent, AnchorPosition.MIDDLECENTER);
    

    or the whole thing:

    var startUnits = app.preferences.rulerUnits; 
    app.preferences.rulerUnits = Units.PIXELS;
    
    var doc = app.activeDocument;
    var res = doc.resolution; // not used, but otherwise useful
    var layer = doc.activeLayer;
    var canvasWidth = doc.width.value;
    var canvasHeight = doc.height.value;
    var borderWidth = canvasHeight * 0.05;
    var newWidth = canvasWidth - (2 * borderWidth);
    var newHeight = newWidth * (canvasHeight/canvasWidth);
    var scalePercent = (newWidth/canvasWidth)*100;
    layer.resize(scalePercent, scalePercent, AnchorPosition.MIDDLECENTER);
    
    // Put the units back to how they were
    app.preferences.rulerUnits = startUnits;
    

    That will resize a layer of 1000 x 300 to 700 x 2100 pixels.