Skip to main content
Known Participant
October 21, 2022
解決済み

Transform a group of layers to all reach the top and bottom of canvas

  • October 21, 2022
  • 返信数 6.
  • 943 ビュー

Hello, 

 

I am loading in a bunch of images of varying sizes. They scale to the sides by default in photoshop. However, for my purpose it would be better if they all scaled to the top and bottom. Is there any way to dfo this within photoshop natively, or a script to do this if not? 



Thank you!

Using PS 2021
Windows

このトピックへの返信は締め切られました。
解決に役立った回答 Chuck Uebele

Okay, try this script. It will cycle through all the Smart Object layers at the top level and resize them. It will not do any layers in groups.

 

#target photoshop 
var doc = activeDocument
app.preferences.rulerUnits = Units.PIXELS;
var layBounds

for(var i=0;i<doc.layers.length;i++){
    doc.activeLayer = doc.layers[i];
    layBounds = doc.activeLayer.bounds;
    if(doc.activeLayer.kind == 'LayerKind.SMARTOBJECT'){
        var ratio =doc.height.value/ (layBounds[3].value-layBounds[1].value);
        doc.activeLayer.resize (ratio *100, ratio*100);
        layBounds = doc.activeLayer.bounds;
        var soCenterX = (layBounds[0].value + layBounds[2].value)/2
        var soCenterY = (layBounds[1].value + layBounds[3].value)/2
        doc.activeLayer.translate ((doc.width.value/2)-soCenterX, (doc.height.value/2)-soCenterY)
        }
    }//end for loop

返信数 6

Chuck Uebele
Community Expert
Chuck UebeleCommunity Expert解決!
Community Expert
October 23, 2022

Okay, try this script. It will cycle through all the Smart Object layers at the top level and resize them. It will not do any layers in groups.

 

#target photoshop 
var doc = activeDocument
app.preferences.rulerUnits = Units.PIXELS;
var layBounds

for(var i=0;i<doc.layers.length;i++){
    doc.activeLayer = doc.layers[i];
    layBounds = doc.activeLayer.bounds;
    if(doc.activeLayer.kind == 'LayerKind.SMARTOBJECT'){
        var ratio =doc.height.value/ (layBounds[3].value-layBounds[1].value);
        doc.activeLayer.resize (ratio *100, ratio*100);
        layBounds = doc.activeLayer.bounds;
        var soCenterX = (layBounds[0].value + layBounds[2].value)/2
        var soCenterY = (layBounds[1].value + layBounds[3].value)/2
        doc.activeLayer.translate ((doc.width.value/2)-soCenterX, (doc.height.value/2)-soCenterY)
        }
    }//end for loop
Stephen Marsh
Community Expert
Community Expert
October 25, 2022

@happyplant1111 - So how did the latest script from Chuck work for you?

Stephen Marsh
Community Expert
Community Expert
October 22, 2022

Here I have combined the script from @Chuck Uebele with some code from @jazz-y to process selected layers... The script will select all layers then resize them. A single history step undo is also included.

 

/* 
Resize All Layers to Doc Height.jsx
https://community.adobe.com/t5/photoshop-ecosystem-discussions/transform-a-group-of-layers-to-all-reach-the-top-and-bottom-of-canvas/m-p/13286952#M679932
*/

#target photoshop

function main() {

    // Select all layers except the Background layer
    app.runMenuItem(stringIDToTypeID('selectAllLayers'));

    ///// Process selected layers - from jazz-y /////
    var s2t = stringIDToTypeID;
    (r = new ActionReference()).putProperty(s2t('property'), p = s2t('targetLayersIDs'));
    r.putEnumerated(s2t('document'), s2t('ordinal'), s2t('targetEnum'));
    var lrs = executeActionGet(r).getList(p),
        sel = new ActionReference();
    for (var i = 0; i < lrs.count; i++) {
        sel.putIdentifier(s2t('layer'), p = lrs.getReference(i).getIdentifier(s2t('layerID')));
        (r = new ActionReference()).putIdentifier(s2t('layer'), p);
        (d = new ActionDescriptor()).putReference(s2t("target"), r);
        executeAction(s2t('select'), d, DialogModes.NO);

        ///// Resize Active Layer to Doc Height - from Chuck Uebele ///// 

        var doc = activeDocument;

        var layBounds = doc.activeLayer.bounds;
        var ratio = doc.height.value / (layBounds[3].value - layBounds[1].value);
        doc.activeLayer.resize(ratio * 100, ratio * 100);
        layBounds = doc.activeLayer.bounds;
        var soCenterX = (layBounds[0].value + layBounds[2].value) / 2;
        var soCenterY = (layBounds[1].value + layBounds[3].value) / 2;

        doc.activeLayer.translate((doc.width.value / 2) - soCenterX, (doc.height.value / 2) - soCenterY);

    }
}
app.activeDocument.suspendHistory("Resize Selected Layers to Doc Height", "main()");

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save the text file as .txt
  5. Rename the file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see link below)

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

Known Participant
October 22, 2022

Wow you guys rock! I will give this a try in a bit and report back. Thanks!!

Stephen Marsh
Community Expert
Community Expert
October 22, 2022
// Resize Active Layer to Doc Height.jsx

// Set the ruler units
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

// Target height
var docHeight = activeDocument.height.value;

resizeToDocHeight();

// Reveal hidden content
//activeDocument.revealAll();

// Restore the original ruler units
app.preferences.rulerUnits = originalRulerUnits;


function resizeToDocHeight() {
    if (!documents.length) return;
    var startRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
    var doc = app.activeDocument;
    // var res = doc.resolution;
    var dHeight = doc.height;
    var LB = activeDocument.activeLayer.bounds;
    var Height = LB[3].value - LB[1].value;
    var onePix = 100 / Height;
    var newSize = onePix * dHeight;
    doc.activeLayer.resize(newSize, newSize, AnchorPosition.MIDDLECENTER);
    app.preferences.rulerUnits = startRulerUnits;
}
Known Participant
October 22, 2022

This is also close to what I need but the same issue as @Chuck Uebele 's 

 

 

After running it seems to only scale based upon the largest layer and the smaller layers are not scaled vertically. 

Stephen Marsh
Community Expert
Community Expert
October 22, 2022

Not in my tests.

 

My canvas was intentionally landscape, with the height the required size. After all layers were scaled to the doc height, the trim command, crop tool or canvas size command can centre crop.

Chuck Uebele
Community Expert
Community Expert
October 22, 2022

Try this script. It will transform a layer to the height of the document and center it. This script will only transfor the selected layer.

@Stephen Marsh Something must have changed, as I didn't have any issues transforming a scaled smart object.

 

 

#target photoshop 
var doc = activeDocument

var layBounds = doc.activeLayer.bounds;
var ratio =doc.height.value/ (layBounds[3].value-layBounds[1].value);
doc.activeLayer.resize (ratio *100, ratio*100);
layBounds = doc.activeLayer.bounds;
var soCenterX = (layBounds[0].value + layBounds[2].value)/2
var soCenterY = (layBounds[1].value + layBounds[3].value)/2

doc.activeLayer.translate ((doc.width.value/2)-soCenterX, (doc.height.value/2)-soCenterY)

 

Stephen Marsh
Community Expert
Community Expert
October 22, 2022

Hi Chuck, you are right, I tried with/without the below code with the same result:

 

// Reset SO transformations
var idplacedLayerResetTransforms = stringIDToTypeID( "placedLayerResetTransforms" );
executeAction(idplacedLayerResetTransforms, undefined, DialogModes.NO);

 

I too modified an existing script, however, you beat me to it! I may as well post the code anyway...

 

Chuck Uebele
Community Expert
Community Expert
October 22, 2022

I most likely can be done with a script, but sizing smart objects in a script can be tricky if they've been previous scaled, which seems to be the case, in your situation.  I bet @jazz-y knows how to scale them properly.

Stephen Marsh
Community Expert
Community Expert
October 22, 2022

I think portrait is the problem for receiving portrait images. If the target is landscape they would resize to the correct height. Then the trim would make a portrait canvas. Or so goes my untested theory.

 

I think that SL can record resetting the SO transform, or it may not matter to just resize the SO a second time to proportionally scale to canvas height.

Chuck Uebele
Community Expert
Community Expert
October 22, 2022

I believe the issue with transforming SOs is that if it has been transformed say 10% smaller, and you get the bounds of the current size and you figure you need to reduce it 20%, well it will throw out that original 10% resize and the new transform will be 20% when it should have been 30%. You need to find out the current transform before you transform. At least I think that is the issue. 

Stephen Marsh
Community Expert
Community Expert
October 21, 2022
quote

Hello, 

 

I am loading in a bunch of images of varying sizes. They scale to the sides by default in photoshop.


By @happyplant1111

 

How are you doing this exactly? Load layers into stack script? Are the resulting layers smart objects?

Known Participant
October 22, 2022

I am just dragging them in to the document. Yes, they are smart objects.