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

Loop Action to Perspective Warp and Resize

Participant ,
Mar 14, 2024 Mar 14, 2024

Copy link to clipboard

Copied

Hail to all the bright minds out there! 👋🏻

 

I would like help reducing the time it takes to combine a bunch of photos of boxes that were not all taken from the same angle.

 

The current steps are:

  • Open up a template
  • Drag and drop the required jpgs as smart layers
  • Run an action to edit the first photo smart layer and perspective crop them to make all corners 90˚
  • Save and Close
  • Make the image background transparent
  • Resize the layer to a specific size (out of proportion if needed) eg. 600x600px
  • Select the next layer
  • Run the action again
  • etc
  • When all layers are done, arrange them in a grid.

 

Screenshot 2024-03-14 at 15.00.53.png

Already achieved

I have created an action that does almost all steps except the resize to a specific size.

 

Need help with:

  1. Resizing the layer to a specific size
  2. Loop the action; currently, when looping with a script, I get the error "Could not complete the Play command because the action is already playing."
  3. When all is done, distribute all layers in the folder "PHOTOS" on a variable grid. Sometimes, I have 4, sometimes 6, and maybe I need to extend the template in the future to have space for more.

 

Attached is a folder of the action, scripts, and files

Documents 

 

I am unsure what is or is not achievable to automate, but any help is much appreciated! 🙏🏻

TOPICS
Actions and scripting , macOS

Views

978

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 , Apr 05, 2024 Apr 05, 2024

Screenshot 2024-04-07 at 12.31.33.pngScreenshot 2024-04-07 at 12.31.52.png

 

// convert smart object with four point vector mask into smart object and transform so that the vector mask is square according to the four guides;
// 2024, use it at your own risk;
if (app.documents.length > 0) {
// set to pixels;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
////////////////////////////////////
// determine the target area;
var theID = getLayerId ();
var theTargetArea = getGuidesSquare ();
if (theTargetArea) {var theTarget =
...

Votes

Translate

Translate
Adobe
Participant ,
Mar 14, 2024 Mar 14, 2024

Copy link to clipboard

Copied

Number 2 is solved by Mastermind c.pfaffenbichler 🙏🏻🤩

See this post

 

 

// 2024, use it at your own risk;
if (app.documents.length > 0) {
var check = isSmartObject();
while (check == true) {
app.doAction("Action 22", "Set 1")
var desc6 = new ActionDescriptor();
var ref4 = new ActionReference();
ref4.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Bckw" ) );
desc6.putReference( charIDToTypeID( "null" ), ref4 );
desc6.putBoolean( charIDToTypeID( "MkVs" ), false );
executeAction( charIDToTypeID( "slct" ), desc6, DialogModes.NO );
check = isSmartObject();
};
};
////// is smart object //////
function isSmartObject (theId) {
var ref = new ActionReference();
ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("smartObject"));
if (theId) {ref.putIdentifier( charIDToTypeID("Lyr "), theId )}
else {ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ))};
var layerDesc = executeActionGet(ref);
var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
return isSmartObject
};

 

 

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 ,
Apr 05, 2024 Apr 05, 2024

Copy link to clipboard

Copied

To help in selecting the relevant elements you could try using the Object Selection Tool and »Mask All Objects« (then combining the relevant Layer Masks) to get a starting-off point. 

Manual amendments will likely be unavoidable, though. 

 

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

Can anyone (maybe c.pfaffenbichler 🙏🏻) help with the resize step?

I can find a resize layer script, but this works with percentages. I want to resize all my smart object layers to a specific pixel width and height, disregarding proportions.

 

OR... the Ferrari script 🤯

 

IF ratio width - height is 1:1 with a margin of 10% difference allowed THEN 600x600px
ELSE width is 600 px

 

 

I do not have much to offer in terms of scripting, but my gratitude would be tremendous if you are ever in need of a designer to lend a hand, I am yours 🤗

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

I am busy at the moment; @Stephen_A_Marsh , please forgive the intrusion but do you have some spare time at current? 

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

quote

I am busy at the moment; @Stephen_A_Marsh , please forgive the intrusion but do you have some spare time at current? 


By @c.pfaffenbichler

 

Yes, all good!

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

quote

Can anyone (maybe c.pfaffenbichler 🙏🏻) help with the resize step?

I can find a resize layer script, but this works with percentages. I want to resize all my smart object layers to a specific pixel width and height, disregarding proportions.

 

OR... the Ferrari script 🤯

 

IF ratio width - height is 1:1 with a margin of 10% difference allowed THEN 600x600px
ELSE width is 600 px

 

I do not have much to offer in terms of scripting, but my gratitude would be tremendous if you are ever in need of a designer to lend a hand, I am yours 🤗


By @Esther Netherlands

 

 

So if the edited smart object canvas was 1100 x 1000 px (or vice versa) – would you be happy with the canvas being resized and cropped from the centre to 600 x 600 px canvas size, destructively deleting content?

 

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

@Stephen_A_Marsh first of all, thank you for your time! 🙏🏻
Not the canvas, the layer itself, but yes indeed. In the top post is a zip file with examples of hypothetical images. I did not add one for the if-else, though, but basically, it would be such a box but with a person behind it. In that case I would like to keep the proportions, but make it 600px width.

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

The Smart Object (SO) layer without transformations is sized by the canvas size of the original SO. Resize the SO, save and close – and the SO layer size is then updated.

 

Test the following code with care on duped images as it is destructive to the SO content (of greater concern for linked SO files than embedded):

 

resizeSOto600px();

function resizeSOto600px() {
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
    // Check if the document width is approximately equal to the document height within a tolerance of +/- 10%
    if (conditionalDifferenceResize()) {
        app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
        app.activeDocument.resizeImage (600, undefined, undefined, ResampleMethod.BICUBIC);
        app.activeDocument.resizeCanvas(undefined, 600, AnchorPosition.MIDDLECENTER);
        app.activeDocument.close(SaveOptions.SAVECHANGES);
    } else {
        app.runMenuItem(stringIDToTypeID('placedLayerEditContents'));
        app.activeDocument.resizeImage (600, undefined, undefined, ResampleMethod.BICUBIC);
        app.activeDocument.close(SaveOptions.SAVECHANGES);
    }
    app.preferences.rulerUnits = originalRulerUnits;

    function conditionalDifferenceResize() {
        var originalRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;
        var theWidth = app.activeDocument.width.value;
        var theHeight = app.activeDocument.height.value;
        var theDifference = Math.abs((theWidth - theHeight) / ((theWidth + theHeight) / 2)) * 100;
        app.preferences.rulerUnits = originalRulerUnits;
        if (theDifference <= 10) {
            return true;
        } else {
            return false;
        }
    }
}

 

P.S. If the SO canvas has transparent pixels, I might need to add a step to trim to transparency before resizing.

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 ,
Mar 15, 2024 Mar 15, 2024

Copy link to clipboard

Copied

Thanks; however, I aim not to damage the Smart Object itself.

 

I did test out the script, but even if I would accept that I will need to adjust/damage the SO, the end result was not as desired.

 

- The SO is not resized out of proportions (SO box 1  is 1 : 1.07)

- The SO in the template file it is not reset to 100% and ending up smaller.

- Due to the resize, the mask does not match anymore - This step I can move in the process though.

 

Here are Video's of the first part of the process, where after placing the images, I do the perspective warp and masking transparency (note: currently crudely done, but this step will be replaced when I have found a solution to remove the background in a good way. Object select etc doesn't do a good job, I am looking into remove.bg plugin options).

 

2nd video is of the next step, the resize step, with your script @Stephen_A_Marsh 

 

 

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 ,
Mar 16, 2024 Mar 16, 2024

Copy link to clipboard

Copied

Could you please provide a layered samlpe file that illustrates the exact state (transformation, Masking, …) of the SO that you want to scale to 600px x 600px? 

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 ,
Mar 16, 2024 Mar 16, 2024

Copy link to clipboard

Copied

Sure!

It is actually in the zip file I provided in the top post, but I added it to the Google folder  I made along the way. Here is the final result I am looking for Boxes.psd 

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 ,
Mar 17, 2024 Mar 17, 2024

Copy link to clipboard

Copied

I would recommend another workflow. 

• Apply a four-point-Vector Mask to the untransformed Smart Object. 

• Automate the transformation from there (the SO will be converted to a SO, so that the bounds of the Vector Mask will be honored in the transformation). 

The Script I adapted works based on the shortest side, so the result may be rotated, though. 

Screenshot 2024-03-17 at 15.29.15.pngScreenshot 2024-03-17 at 15.29.28.png

 

 

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 ,
Mar 18, 2024 Mar 18, 2024

Copy link to clipboard

Copied

😱 Oh wow, that looks like a huge amount of work you did for me, @c.pfaffenbichler. I will dive into it right now (and it will take me a bit of time) and test it out, but I wanted to thank you in advance!!

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 ,
Mar 18, 2024 Mar 18, 2024

Copy link to clipboard

Copied

Yeah, I see what you mean with the rotation, and that is indeed an issue when a person is standing behind the box. It flips it upside down. Not only that, all is transformed into a square as well. The script is amazing and fast though... 🤯

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 ,
Mar 18, 2024 Mar 18, 2024

Copy link to clipboard

Copied

I updated the Boxes.psd with a fake example (sorry should have done this from the start 😔) of a person on the box. It would be freakin amazing if the vector mask could start with the box selection, all transformations to be done based on the box (as the true aim is to get all the boxes the same dimension, and only enlarging of the vector mask as a last step was needed.

 

Truly I am so grateful and do not know how to repay you @c.pfaffenbichler I am learning so much from your script and way of thinking (never considered a vector mask!) already, and secretly hope you will be able to pull of one more rabbit out of that hat of yours and get me to the finish line with this process so I can start efficiently and fast working through my photos 🙏🏻

 

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 ,
Mar 19, 2024 Mar 19, 2024

Copy link to clipboard

Copied

@c.pfaffenbichler I tried adjusting your method, but it was too challenging for me to overcome/solve the flipped and all photos to square.

 

But with all the help from you, @Stephen_A_Marsh + some google/chatPGT I did get my flow to work 💪🏻

PS: the 600px in my initial became 400px

 

For those interested, these are the steps + scripts:

 

Apply the same action on all Smart Objects

 

// 20-03-2024 // Run action on all Smart Objects // Based on code by c.pfaffenbichler
if (app.documents.length > 0) {
    var check = isSmartObject();
    while (check == true) {
    app.doAction("Action Name", "Action Set Name")
    var desc6 = new ActionDescriptor();
    var ref4 = new ActionReference();
    ref4.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Bckw" ) );
    desc6.putReference( charIDToTypeID( "null" ), ref4 );
    desc6.putBoolean( charIDToTypeID( "MkVs" ), false );
    executeAction( charIDToTypeID( "slct" ), desc6, DialogModes.NO );
    check = isSmartObject();
    };
    };
    function isSmartObject (theId) {
    var ref = new ActionReference();
    ref.putProperty (stringIDToTypeID ("property"), stringIDToTypeID ("smartObject"));
    if (theId) {ref.putIdentifier( charIDToTypeID("Lyr "), theId )}
    else {ref.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ))};
    var layerDesc = executeActionGet(ref);
    var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
    return isSmartObject
    };

 

 

Action containing 

  1. Edit contents
  2. Perspective Crop
  3. Script Resize based on the ratio

 

// 20-03-2024 // Resize based on ratio // Based on code by Stephen_A_Marsh 
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

if (conditionalDifferenceResize()) {
    app.activeDocument.resizeImage (800, 800, undefined, ResampleMethod.BICUBIC);
    app.activeDocument.resizeCanvas(800, 800, AnchorPosition.MIDDLECENTER);
} else {
    app.activeDocument.resizeImage (800, undefined, undefined, ResampleMethod.BICUBIC);
    app.activeDocument.resizeCanvas(800, undefined, AnchorPosition.MIDDLECENTER);
}
app.preferences.rulerUnits = originalRulerUnits;

function conditionalDifferenceResize() {
    var theWidth = app.activeDocument.width.value;
    var theHeight = app.activeDocument.height.value;
    var theDifference = Math.abs(theWidth / theHeight);
    if (theDifference <= 1.1 && theDifference >= 0.9) {
        return true;
    } else {
        return false;
    }
}

 

 

4. Save and Close

5. Script to Resize 50% > Align Top Left Canvas > Move into position

 

// 20-03-2024 // Scale and move Smart Object into position
if (app && app.documents.length > 0) {
    var doc = app.activeDocument;
    var originalRulerUnits = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;
    
    ////// Transform Layer 50% //////
    runMenuItem(stringIDToTypeID('placedLayerResetTransforms'));
    doc.activeLayer.resize(50, 50)

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

    ////// Move to Coordinates //////
    var docWidth = doc.width;
    var docHeight = doc.height;
    var offsetX = 2900;
    var offsetY = 2140;
    var layerBounds = doc.activeLayer.bounds;
    var layerWidth = layerBounds[2] - layerBounds[0]; // width of the layer
    var layerHeight = layerBounds[3] - layerBounds[1]; // height of the layer
    var newX = layerBounds[0] + offsetX - layerWidth; // new X coordinate
    var newY = layerBounds[1] + offsetY - layerHeight; // new Y coordinate
    doc.activeLayer.translate(newX, newY);
    }

 

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 ,
Mar 19, 2024 Mar 19, 2024

Copy link to clipboard

Copied

I have an idea about how to address the rotation and the »content-beyond-the-square«-issue but I am busy at current. 

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 ,
Mar 21, 2024 Mar 21, 2024

Copy link to clipboard

Copied

I adapted the Script a bit; extending the Smart Object’s Canvas will maintain the distortion, I just added 2000px instead of checking for content extending further, though. edited 2024-04-03

Screenshot 2024-03-21 at 14.30.00.pngScreenshot 2024-03-21 at 14.29.17.pngScreenshot 2024-03-21 at 14.29.49.png

edited

 

 

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

Sorry @c.pfaffenbichler I had some personal things to take care of before able to get back to my project.

 

I just tried your code, I got errors on lines 312 and 313, but ChatGPT's fix worked:

    // by xbytor, thanks to him;
    function cTID(s) { return app.charIDToTypeID(s); }
    function sTID(s) { return app.stringIDToTyp eID(s); }
    // reset;

 

I have just one "issue," again, due to my not fully considering all the possibilities. It is not only the top side that potentially contains the image I want to keep. Sometimes, something hangs over the sides or bottom, too. By the looks of my tests, it cuts all sides except the top (and creates a bottom blank space?).

 

But I am in aweeeee, like WOW!! No words, if this could work it would reduce my time soooo much. So I am hesitant to ask 🫣, but could you take one more crack at this for me 🙏🏻?

 

I have updated the PSD with some (roughly and random) versions of the sides possible.

 

And if no, not possible, I do want to thank you for all your great work and wisdom!

 

 

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

I updated the code in the previous post, please try that. 

Screenshot 2024-04-03 at 12.35.20.pngScreenshot 2024-04-03 at 12.35.28.png

Screenshot 2024-04-03 at 12.37.56.pngScreenshot 2024-04-03 at 12.38.10.png

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

... I am speechless, I am beyond grateful @c.pfaffenbichler 🙏🏻🙏🏻🙏🏻🙏🏻🙏🏻

It works PERFECT!! 

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

Good to know it is helpful. 

But it only provides semi-automation, the 4-point-Vector Mask still needs to be created manually. 

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

That is true, but just one step for me instead of 6+ steps is a huge time reduction. My project, therefore, seems less daunting and doable now. Thanks again. You are a generous genius! 🤩

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 ,
Apr 03, 2024 Apr 03, 2024

Copy link to clipboard

Copied

One question though @c.pfaffenbichler , just for cleanliness, if I check the original smart object, it has an additional "canvas" area and guidelines in it. Is this enlarging my files? Is it something easy to avoid/remove?

 

Screenshot 2024-04-03 at 16.04.38.png

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