• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Fit Layer To Canvas Keeping Aspect Ratio

Guest
Jun 17, 2019 Jun 17, 2019

Copy link to clipboard

Copied

Hello

I'm currently using the below script to resize a layer to fit the canvas, however I would like to adjust it so it keeps in ratio. It currently stretches the whole layer to fit the canvas which isn't quite what I'm after. I would like it to fit specifically to the width or the height of the canvas depending if the layer content is wider than it is tall or vice-versa. Unfortunately I have zero scripting skills and am at a complete loss on what to adjust. Any help would be fantastic.

var maintainAspectRatio;// set to true to keep aspect ratio 

    if(app.documents.length>0){ 

        app.activeDocument.suspendHistory ('Fit Layer to Canvas', 'FitLayerToCanvas('+maintainAspectRatio+')'); 

    } 

    function FitLayerToCanvas( keepAspect ){// keepAspect:Boolean - optional. Default to false 

        var doc = app.activeDocument; 

        var layer = doc.activeLayer; 

        // do nothing if layer is background or locked 

        if(layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked 

                                || layer.positionLocked || layer.transparentPixelsLocked ) return; 

        // do nothing if layer is not normal artLayer or Smart Object 

        if( layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return; 

        // store the ruler 

        var defaultRulerUnits = app.preferences.rulerUnits; 

        app.preferences.rulerUnits = Units.PIXELS; 

         

        var width = doc.width.as('px'); 

        var height =doc.height.as('px'); 

        var bounds = app.activeDocument.activeLayer.bounds; 

        var layerWidth = bounds[2].as('px')-bounds[0].as('px'); 

        var layerHeight = bounds[3].as('px')-bounds[1].as('px'); 

             

        // move the layer so top left corner matches canvas top left corner 

        layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px')); 

        if( !keepAspect ){ 

            // scale the layer to match canvas 

            layer.resize( (width/layerWidth)*100,(height/layerHeight)*100,AnchorPosition.TOPLEFT); 

        }else{ 

            var layerRatio = layerWidth / layerHeight; 

            var newWidth = width; 

            var newHeight = ((1.0 * width) / layerRatio); 

            if (newHeight >= height) { 

                newWidth = layerRatio * height; 

                newHeight = height; 

            } 

            var resizePercent = newWidth/layerWidth*100; 

            app.activeDocument.activeLayer.resize(resizePercent,resizePercent,AnchorPosition.TOPLEFT); 

        } 

        // restore the ruler 

        app.preferences.rulerUnits = defaultRulerUnits; 

    } 

TOPICS
Actions and scripting

Views

4.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jun 17, 2019 Jun 17, 2019

I just posted this in another topic thread (this code is the opposite, it maintains proportion, the other script code stretches):

 

// FIT LAYER TO CANVAS 
// via https://forums.adobe.com/message/5413957#5413957 
// https://gist.githubusercontent.com/jawinn/ab4df1c33d0743e41fd3/raw/72ff297ae42ed029c86be7644bd021ef4... 
var maintainAspectRatio = true; // set to true to keep aspect ratio, false to stretch/distort to fit   
if (app.documents.length > 0) {
    app.activeDocument.suspendHistory('Fit 
...

Votes

Translate

Translate
Adobe
Community Expert ,
Jun 17, 2019 Jun 17, 2019

Copy link to clipboard

Copied

I just posted this in another topic thread (this code is the opposite, it maintains proportion, the other script code stretches):

 

// FIT LAYER TO CANVAS 
// via https://forums.adobe.com/message/5413957#5413957 
// https://gist.githubusercontent.com/jawinn/ab4df1c33d0743e41fd3/raw/72ff297ae42ed029c86be7644bd021ef4... 
var maintainAspectRatio = true; // set to true to keep aspect ratio, false to stretch/distort to fit   
if (app.documents.length > 0) {
    app.activeDocument.suspendHistory('Fit Layer to Canvas', 'FitLayerToCanvas(' + maintainAspectRatio + ')');
}

function FitLayerToCanvas(keepAspect) { // keepAspect:Boolean - optional. Default to false   
    var doc = app.activeDocument;
    var layer = doc.activeLayer;
    // do nothing if layer is background or locked   
    if (layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked ||
        layer.positionLocked || layer.transparentPixelsLocked) return;
    // do nothing if layer is not normal artLayer or Smart Object   
    if (layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;
    // store the ruler   
    var defaultRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    var width = doc.width.as('px');
    var height = doc.height.as('px');
    var bounds = app.activeDocument.activeLayer.bounds;
    var layerWidth = bounds[2].as('px') - bounds[0].as('px');
    var layerHeight = bounds[3].as('px') - bounds[1].as('px');

    // move the layer so top left corner matches canvas top left corner   
    layer.translate(new UnitValue(0 - layer.bounds[0].as('px'), 'px'), new UnitValue(0 - layer.bounds[1].as('px'), 'px'));
    if (!keepAspect) {
        // scale the layer to match canvas   
        layer.resize((width / layerWidth) * 100, (height / layerHeight) * 100, AnchorPosition.TOPLEFT);
    } else {
        var layerRatio = layerWidth / layerHeight;
        var newWidth = width;
        var newHeight = ((1.0 * width) / layerRatio);
        if (newHeight >= height) {
            newWidth = layerRatio * height;
            newHeight = height;
        }
        var resizePercent = newWidth / layerWidth * 100;
        app.activeDocument.activeLayer.resize(resizePercent, resizePercent, AnchorPosition.TOPLEFT);
    }
    // restore the ruler   
    app.preferences.rulerUnits = defaultRulerUnits;
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Jun 17, 2019 Jun 17, 2019

Copy link to clipboard

Copied

This is perfect, thank you so much!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 19, 2019 Jun 19, 2019

Copy link to clipboard

Copied

Glad to be of help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 20, 2022 Jan 20, 2022

Copy link to clipboard

Copied

Escuse me sr, this script can work with text layers ?

I tried to use this amazing script but it only work when I turn the text layer into a smart object,

Unfortunatelly transformations are lost if I turn the smart object back to layers,

Thank you very much for your help.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 20, 2022 Jan 20, 2022

Copy link to clipboard

Copied

You can try commenting out line 15 with double forward slashes // at the start of the line:

 

//if( layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;   

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jan 20, 2022 Jan 20, 2022

Copy link to clipboard

Copied

Thank you, I did it but it does not do anything, the text layer still outside the document boundaries. ( I want to fit a long text inside)

thank you

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jan 20, 2022 Jan 20, 2022

Copy link to clipboard

Copied

Perhaps something like this?

 

#target photoshop

function fitLayer() {

    if (documents.length > 0) {

        // Save the original dialog display
        var originalDialogMode = app.displayDialogs;
        app.displayDialogs = DialogModes.ERROR;
        // Save the original ruler units
        var originalRulerUnits = app.preferences.rulerUnits;
        // Set the working units
        app.preferences.rulerUnits = Units.PIXELS;
        // Save the original resolution
        var originalRes = app.activeDocument.resolution;

        try {

            app.preferences.rulerUnits = Units.PIXELS;

            // Conditional resize layer by portrait or landscape orientation
            if (app.activeDocument.height > app.activeDocument.width) {
                scaleP();
            } else {
                scaleL();
            }

            // Reset the original settings
            app.preferences.rulerUnits = originalRulerUnits;
            app.displayDialogs = originalDialogMode;
            app.activeDocument.resolution = originalRes;

            function scaleP() {
                var iLayer = app.activeDocument.activeLayer;
                app.activeDocument.activeLayer = iLayer;
                var scale = Math.min(app.activeDocument.width / (iLayer.bounds[2] - iLayer.bounds[0]), app.activeDocument.width / (iLayer.bounds[3] - iLayer.bounds[1]));
                // Scale to 90% of canvas
                iLayer.resize(scale * 100, scale * 100);
                // Centre the text layer on canvas
                iLayer.translate(app.activeDocument.width / 2 - (iLayer.bounds[0] + iLayer.bounds[2]) / 2, app.activeDocument.height / 2 - (iLayer.bounds[1] + iLayer.bounds[3]) / 2);
            }

            function scaleL() {
                var iLayer = app.activeDocument.activeLayer;
                app.activeDocument.activeLayer = iLayer;
                var scale = Math.min(app.activeDocument.width / (iLayer.bounds[2] - iLayer.bounds[0]), app.activeDocument.height / (iLayer.bounds[3] - iLayer.bounds[1]));
                // Scale to 90% of canvas
                iLayer.resize(scale * 100, scale * 100);
                // Centre the text layer on canvas
                iLayer.translate(app.activeDocument.width / 2 - (iLayer.bounds[0] + iLayer.bounds[2]) / 2, app.activeDocument.height / 2 - (iLayer.bounds[1] + iLayer.bounds[3]) / 2);
            }

        } catch (e) {
            // Reset the original settings
            app.preferences.rulerUnits = originalRulerUnits;
            app.displayDialogs = originalDialogMode;
            app.activeDocument.resolution = originalRes;

            return;
        }
    }
}

// Create a single history step
app.activeDocument.suspendHistory("Fit Layer Proportionally", "fitLayer()");

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 17, 2022 Dec 17, 2022

Copy link to clipboard

Copied

Won't the last step cause an error on older illustrator versions? I work with 2018cc at work due to old computer. But it doesn't have the history panel. I think you should then add of statement app.version, not 100% what the exact code is, but i know we can get the app version somehow

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 17, 2022 Dec 17, 2022

Copy link to clipboard

Copied

@schroef – this is of course true, not all features are applicable to all versions. I presume that you mean Photoshop and not Illustrator.

 

For recent features where I remember them, such as in Photoshop 2022 (v23.x.x) or later, there is native WebP support. So if saving in that format, I put in a version check.

 

For older features from before I started scripting, I can't remember the relationship of "feature X is limited to version Y", so I don't put in a version check. I haven't had any reports of failures with code for suspendHistory so I figure that anybody using the code is running a capable version.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 17, 2022 Dec 17, 2022

Copy link to clipboard

Copied

LATEST

Yeah sorry your right, didn't noticed this was a Photoshop category. Was checking it on mobile and you hardly see the info

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Jun 05, 2022 Jun 05, 2022

Copy link to clipboard

Copied

perfect, thank you

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Nov 27, 2022 Nov 27, 2022

Copy link to clipboard

Copied

Great job. Thanks!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Jan 31, 2020 Jan 31, 2020

Copy link to clipboard

Copied

Does anyone know how i can reset scale to 100%. Im trying make simple script, but the resize function works with percentage, so simply using 100 doesnt do anything. I cant find the reference for this in the scripting documents. Neither does there exist a simple function "reset scale" or "reset transformation". At least not that i know of

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Dec 17, 2022 Dec 17, 2022

Copy link to clipboard

Copied

quote

Does anyone know how i can reset scale to 100%.


By @schroef

 

@schroef – I know that this is an old post, however, your activity has now brought it to my attention... If you were referring to resetting a smart object transformation:

 

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines