Skip to main content
Esther Netherlands
Inspiring
May 17, 2024
Answered

Script to import, warp, resize and move layers

  • May 17, 2024
  • 2 replies
  • 2275 views

Hey, all the generous and bright minds out there 🤩

 

I would like help reducing the time it takes to make a collage of multiple photos of wooden boxes. In the past months, I had amazing help from c.pfaffenbichler and Stephen_A_Marsh regarding this process.

 

c.pfaffenbichler created a script to skew smart objects that worked most of the time - See post HERE. However, a bug created stretched images very inconsistently. I read online this happened to others using actions and Smart Objects. Besides this my "input files" changed, instead of jpgs, I am now dealing with PSD files with a layer mask created by Remove.bg.

 

I would like to have the layer mask of transparency in my input files directly editable in my template file. It made me decide to abandon the desire to keep the original photo information and quality. Unfortunately, this also means the powerhouse of a script he created for me can't do the job anymore. 🥺

 

I would like to ask again for help 🙏

 

Process steps

  •  Start ingredients:
    - Template file (Framefoto-template NEW v2.psd)
    - Multiple PSD files containing 2 layers, where 1 is a layer of the photo with a layer mask (box 1.psd, box 2.psd, box 5.psd)
  • 1st step script desired - fetch and copy layers with mask:
    - Pop-up to multi-select PSD files of the boxes
    - Script to look for layers with a mask (if needed, currently always is 1 named remove.bg)
    - Layer, including the mask, copied to the active document (Template file) into the layerset "FOTOS"
    - Layer name renamed to the original file (if this is even possible)
    - IF layer > then canvas height/width resize to fit
    - Center on canvas

 

     





 


          See result example PSD file

  • 2nd step script desired - transform per photo:
    - manually 4 points will be assigned by the user
    - based on the 4 points, skew/perspective warp to make corners 90˚
    - based on the 4 points area, Resize image + mask to make the area 800x800 pixels
    - based on the 4 points area, Move the layer to static coordinates

 

     




 



          See result example PSD file

Video of the process manually

Folder containing all example files

 

Potential useful Information

The information below was recorded during the perspective warp action. I replaced the parts that should be based on the manual assigned 4 points by the user. 

 

 

 

Action:
Perspective Warp current layer
Mode: Warp
Reference Bounds: rectangle
Top: [VARIABLE INPUT] pixels
Left: [VARIABLE INPUT] pixels
Bottom: [VARIABLE INPUT] pixels
Right: [VARIABLE INPUT] pixels
Vertices: point list
point: [VARIABLE INPUT] pixels, [VARIABLE INPUT] pixels 
point: [VARIABLE INPUT] pixels, [VARIABLE INPUT] pixels 
point: [VARIABLE INPUT] pixels, [VARIABLE INPUT] pixels 
point: [VARIABLE INPUT] pixels, [VARIABLE INPUT] pixels
Warped Vertices: point list 
point: 2500 pixels, 1740 pixels 
point: 2900 pixels, 1740 pixels 
point: 2900 pixels, 2140 pixels 
point: 2500 pixels, 2140 pixels
Quads: Quad list
Quad
Vertex Indices: 0, 1, 2, 3

 

 

 

This topic has been closed for replies.
Correct answer Esther Netherlands

No worries, @Stephen Marsh , I will give it a try myself again. I ran into some issues the first time, but I am sure with some dedication, I indeed can make it happen myself.


It is probably a Frankenstein code, but I got it to work 😅

 

/*
Stack Masked Doc Layers to Template Doc.jsx
v1.0 - 21st May 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-import-warp-resize-and-move-layers/td-p/14623443
*/

if (app.documents.length) {

    (function () {
        if (app.activeDocument.name == 'Framefoto-template.psd') {
            main();
        } else {
            var theConfirmation = (confirm("The active doc isn't named 'Framefoto-template.psd' Continue?", false));
            if (theConfirmation === false) {
                return;
            }
            main();
        }
    })();

} else {
    alert('A document must be open to run this script!');
}


function main() {

    (function () {

        try {
            var savedRuler = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            // Set the active doc as the template doc
            var templateDoc = app.activeDocument;
            var templateDocName = app.activeDocument.name;

            // Ensure that the contents of the FOTO group is active
            if (app.activeDocument.activeLayer.name != 'FOTOS') {
                app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName('FOTOS').layers[0];
            }

            // Select the 'remove.bg' PSD source files
            var selectFile = File.openDialog('Select the file/s:', Multiselect = true);
            if (selectFile === null) {
                return;
            }

            // Loop over the selected files
            for (var i = 0; i < selectFile.length; i++) {

                // Open each selected file
                app.open(File(selectFile[i]));

                // Set the sourceDoc as the active document
                var sourceDoc = app.activeDocument;

                // Select the source layer
                //app.activeDocument.activeLayer = app.activeDocument.layers.getByName('remove.bg');
                app.activeDocument.activeLayer = app.activeDocument.layers[0];

                // Duplicate the source layer to the template doc
                dupeLayer(templateDocName, app.activeDocument.name.replace(/\.[^\.]+$/, ''));

                // Set the template doc as the active document
                app.activeDocument = templateDoc;

                // Resize to 800 pixels according to ratio
                var docWidth = app.activeDocument.width;
                var docHeight = app.activeDocument.height;
                var layerWidth = (app.activeDocument.activeLayer.bounds[2].value - app.activeDocument.activeLayer.bounds[0].value);
                var layerHeight = (app.activeDocument.activeLayer.bounds[3].value - app.activeDocument.activeLayer.bounds[1].value);
            
                // Calculate the aspect ratio
                var aspectRatio = Math.abs(layerWidth / layerHeight);
                var scaleFactorWidth = Math.abs(800 / layerWidth)
                var scaleFactorHeight = Math.abs(800 / layerHeight)
            
                // Calculate the scale factor
                var scale;
                if (aspectRatio <= 1.1 && aspectRatio >= 0.9) {
                    // If aspect ratio within the threshold, scale to fit within 800x800
                    app.activeDocument.activeLayer.resize(scaleFactorWidth * 100,scaleFactorHeight * 100, AnchorPosition.BOTTOMRIGHT);
                } else {
                    // If aspect ratio outside the threshold, resize to 800 width and maintain aspect ratio
                    app.activeDocument.activeLayer.resize(scaleFactorWidth * 100,scaleFactorWidth * 100, AnchorPosition.BOTTOMRIGHT);
                }

                // Align Layer Top Left of Canvas
                app.activeDocument.selection.selectAll();
                var deltaX = app.activeDocument.selection.bounds[0] - app.activeDocument.activeLayer.bounds[0];
                var deltaY = app.activeDocument.selection.bounds[1] - app.activeDocument.activeLayer.bounds[1];
                app.activeDocument.activeLayer.translate(deltaX, deltaY);

                // Move the duped layer on the template canvas
                var offsetX = 5400;
                var offsetY = 4300;
                var layerBounds = app.activeDocument.activeLayer.bounds;
                var layerWidth = layerBounds[2] - layerBounds[0]; // width of the layer
                var layerHeight = layerBounds[3] - layerBounds[1]; // height of the layer
                app.activeDocument.activeLayer.translate(layerBounds[0] + offsetX-(layerWidth/2),layerBounds[1] + offsetY-(layerHeight));

                // Deselect the selection
                app.activeDocument.selection.deselect();

                // Close the source doc
                sourceDoc.close(SaveOptions.DONOTSAVECHANGES);

            }

            app.preferences.rulerUnits = savedRuler;


            // Functions

            function dupeLayer(targetDocName, sourceLayerName) {
                function s2t(s) {
                    return app.stringIDToTypeID(s);
                }
                var descriptor = new ActionDescriptor();
                var list = new ActionList();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(s2t("null"), reference);
                reference2.putName(s2t("document"), targetDocName);
                descriptor.putReference(s2t("to"), reference2);
                descriptor.putString(s2t("name"), sourceLayerName);
                descriptor.putList(s2t("ID"), list);
                executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
            }

        } catch (e) {
            alert('Error!' + '\r' + e + ', Line: ' + e.line);
        }

    })();

}

 

2 replies

Stephen Marsh
Community Expert
Community Expert
May 21, 2024

@Esther Netherlands 

 

Try this:

 

/*
Stack Masked Doc Layers to Template Doc.jsx
v1.0 - 21st May 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/script-to-import-warp-resize-and-move-layers/td-p/14623443
*/

#target photoshop

if (app.documents.length) {

    (function () {
        if (app.activeDocument.name == 'Framefoto-template.psd') {
            main();
        } else {
            var theConfirmation = (confirm("The active doc isn't named 'Framefoto-template.psd' Continue?", false));
            if (theConfirmation === false) {
                return;
            }
            main();
        }
    })();

} else {
    alert('A document must be open to run this script!');
}


function main() {

    (function () {

        try {
            var savedRuler = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;

            // Set the active doc as the template doc
            var templateDoc = app.activeDocument;
            var templateDocName = app.activeDocument.name;

            // Ensure that the contents of the FOTO group is active
            if (app.activeDocument.activeLayer.name != 'FOTOS') {
                app.activeDocument.activeLayer = app.activeDocument.layerSets.getByName('FOTOS').layers[0];
            }

            // Select the 'remove.bg' PSD source files
            var selectFile = File.openDialog('Select the file/s:', Multiselect = true);
            if (selectFile === null) {
                return;
            }

            // Loop over the selected files
            for (var i = 0; i < selectFile.length; i++) {

                // Open each selected file
                app.open(File(selectFile[i]));

                // Set the sourceDoc as the active document
                var sourceDoc = app.activeDocument;

                // Select the source layer
                //app.activeDocument.activeLayer = app.activeDocument.layers.getByName('remove.bg');
                app.activeDocument.activeLayer = app.activeDocument.layers[0];

                // Duplicate the source layer to the template doc
                dupeLayer(templateDocName, app.activeDocument.name.replace(/\.[^\.]+$/, ''));

                // Set the template doc as the active document
                app.activeDocument = templateDoc;

                // Conditionally resize the layer to fit the canvas
                var docWidth = app.activeDocument.width;
                var docHeight = app.activeDocument.height;
                var layerWidth = (app.activeDocument.activeLayer.bounds[2].value - app.activeDocument.activeLayer.bounds[0].value);
                var layerHeight = (app.activeDocument.activeLayer.bounds[3].value - app.activeDocument.activeLayer.bounds[1].value);
                if (layerWidth > docWidth) {
                    //alert('The layer is wider than the canvas!');
                    app.activeDocument.activeLayer.resize((docWidth / layerWidth) * 100, (docWidth / layerWidth) * 100, AnchorPosition.MIDDLECENTER);
                }
                if (layerHeight > docHeight) {
                    //alert('The layer is taller than the canvas!');
                    app.activeDocument.activeLayer.resize((docHeight / layerHeight) * 100, (docHeight / layerHeight) * 100, AnchorPosition.MIDDLECENTER);
                }

                // Centre the duped layer on the template canvas
                app.activeDocument.activeLayer.translate(docWidth / 2 - (app.activeDocument.activeLayer.bounds[0] + app.activeDocument.activeLayer.bounds[2]) / 2,
                    docHeight / 2 - (app.activeDocument.activeLayer.bounds[1] + app.activeDocument.activeLayer.bounds[3]) / 2);

                // Close the source doc
                sourceDoc.close(SaveOptions.DONOTSAVECHANGES);

            }

            app.preferences.rulerUnits = savedRuler;


            // Functions

            function dupeLayer(targetDocName, sourceLayerName) {
                function s2t(s) {
                    return app.stringIDToTypeID(s);
                }
                var descriptor = new ActionDescriptor();
                var list = new ActionList();
                var reference = new ActionReference();
                var reference2 = new ActionReference();
                reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
                descriptor.putReference(s2t("null"), reference);
                reference2.putName(s2t("document"), targetDocName);
                descriptor.putReference(s2t("to"), reference2);
                descriptor.putString(s2t("name"), sourceLayerName);
                descriptor.putList(s2t("ID"), list);
                executeAction(s2t("duplicate"), descriptor, DialogModes.NO);
            }

        } catch (e) {
            alert('Error!' + '\r' + e + ', Line: ' + e.line);
        }

    })();

}

 

Esther Netherlands
Inspiring
May 21, 2024

It works like a charm @Stephen Marsh , Thank you so much for this!

Stephen Marsh
Community Expert
Community Expert
May 21, 2024

You're welcome! I'm concerned with quality loss from multiple transforms, however, I'm not sure if creating a smart object beforehand would help or hinder your later moves?

Esther Netherlands
Inspiring
May 20, 2024

@Stephen Marsh, For the first step, I am trying to adjust the script you shared in another post, which you referred to in my previous post. But I am not succeeding. Would you be able to help me?


If not, absolutely no problem at all! I am already grateful to you and all the experts for sharing your knowledge so freely with me and all the other Photoshop users who are not really scripters! 🙏

Hope to hear from you!

Stephen Marsh
Community Expert
Community Expert
May 20, 2024

@Esther Netherlands  - I should be able to help with step 1.