Need Action That Makes an Equal-Sized Border for Images With Different Sizes

Community Beginner ,
Mar 06, 2021 Mar 06, 2021

Copy link to clipboard

Copied

Can anyone point me in the right direction?

 

I found this forum and it seems similar to what I'm looking for, but I don't know how to create the action: https://community.adobe.com/t5/photoshop/action-that-uses-a-percentage-of-image-size-in-pixel-dimens...

TOPICS
Actions and scripting

Views

264

Likes

translate

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
Adobe Community Professional ,
Mar 06, 2021 Mar 06, 2021

Copy link to clipboard

Copied

The action mentioned in that thread will create an even horizontal/vertical sized border inside the image. Is this what you need help recreating? A 1000px width document with a 4% border based on the width would end up with a visible area of 920px on the width. This will cover existing content with the border.

 

The alternative would be a document that was 1080px on the width, extending the canvas and not covering exising content.

Likes

translate

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 ,
Mar 06, 2021 Mar 06, 2021

Copy link to clipboard

Copied

Hey thanks for the response, I wouldn't want a border that would cover up the image.

 

Basically what I want is to figure out how to make a border that looks consistent with all image sizes. Whenever I go into Image --> Canvas Size... --> and choose the "Percentage" option and add 5% on each option with "Relative" ticked, it'll make a nice border, but if the image is not completely square, one side will be longer than the other.

 

So what I'm trying to figure out is, how can I make a consistent-looking border for all image sizes and make it into an action?

Likes

translate

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
Adobe Community Professional ,
Mar 06, 2021 Mar 06, 2021

Copy link to clipboard

Copied

As the other thread shows, sometimes one has to get creative in an action as they are sometimes limited compared to scripts.

 

It depends on what you call 'consistent', as % based is relative to the image while absolute in pixels is always going to deliver fixed values.

 

I have just created a script that currently only works on flattened images.

 

Do you need this to work on both flattened and layered, or only flattened.

Likes

translate

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
Adobe Community Professional ,
Mar 06, 2021 Mar 06, 2021

Copy link to clipboard

Copied

Try this for horizontal images. The action creates a border of 10% of the narrow side.

 

abc.png

 

For vertical images change the alignment type.

Likes

translate

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 ,
Mar 07, 2021 Mar 07, 2021

Copy link to clipboard

Copied

Oh this looks great! Could you possibly send me the download link for both versions? I'm not very familiar on how to recreate that, would raelly be appreciated!

Likes

translate

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
Adobe Community Professional ,
Mar 07, 2021 Mar 07, 2021

Copy link to clipboard

Copied

What do you not understand there? ))

Here is a link to Action Set.

https://disk.yandex.ru/d/K_H2gO2tg2IGqQ

 

Start Action "Run".

To change the size of the border, edit Action "Transform".

The "Run" action works for both portrait and landscape orientations using an if condition.

 

P.S. It would be much simpler and more flexible to use a script instead of this Action.

Likes

translate

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
Adobe Community Professional ,
Mar 08, 2021 Mar 08, 2021

Copy link to clipboard

Copied

Now I noticed that in the topic from the link in the first message there is my action, which can be redone into what is needed. You just need to remove the first and third command.
 
 
 

Likes

translate

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
Adobe Community Professional ,
Mar 08, 2021 Mar 08, 2021

Copy link to clipboard

Copied

OK, here is that script that I was working on. It grew a little bit once I started the conditional check for a flattened or layered original, then I had to refactor and optimise the code etc.

 

It uses the document's width to base the border % size on. It is easy enough to change this to the doc's height (line 63), see the comments in the file.

 

Please let me know how it goes. 

 

This script uses some GUI input to set colour and border size, it could be adjusted for use with batching.

 

 

/*

Extend Canvas Border by Percentage of Doc Width.jsx
Version 1.0
Stephen Marsh - 2021

Need Action That Makes an Equal-Sized Border for Images With Different Sizes
https://community.adobe.com/t5/photoshop/need-action-that-makes-an-equal-sized-border-for-images-with-different-sizes/td-p/11876979

Action that uses a percentage of image size in pixel dimensions
https://community.adobe.com/t5/photoshop/action-that-uses-a-percentage-of-image-size-in-pixel-dimensions/m-p/9897687

You can change the docWidth.value to docHeight.value for the basis of the frame size on line 63

*/

#target photoshop
app.bringToFront();

// Conditional Background layer check
if (app.activeDocument.activeLayer.isBackgroundLayer) {
    setForeground();
    addBorder();
}
// Otherwise run on layered files
else {
    addBorder();
    addColorFillLayer();
    // "previous" or "next" or "front" or "back"
    moveLayerRelativeStack("back");
}

function addBorder() {

    // Save the current ruler units and set to pixels
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    // Loop the input prompt until a number is entered
    var origInput;
    while (isNaN(origInput = prompt("Enter the border size" + "\n" + "(based on a % of the document's width)", "4")));

    // Test if cancel returns null, then terminate the script
    if (origInput === null) {
        alert('Script cancelled!');
        return
    }

    // Test if an empty string is returned, then terminate the script
    if (origInput === "") {
        alert('A value was not entered, script cancelled!');
        return
    }

    // Convert decimal input to integer
    var borderSize = parseInt(origInput);

    // Border size value in pixels
    var doc = app.activeDocument;
    var docWidth = doc.width;
    var docHeight = doc.height;
    // Change the docWidth.value to docHeight.value for the basis of the frame size
    var canvasExtension = borderSize / 100 * docWidth.value;

    // Resize canvas - relative width & height
    extendCanvasRelative(true, canvasExtension, canvasExtension);

    function extendCanvasRelative(relative, width, height) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        descriptor.putBoolean(s2t("relative"), relative);
        descriptor.putUnitDouble(s2t("width"), s2t("pixelsUnit"), width);
        descriptor.putUnitDouble(s2t("height"), s2t("pixelsUnit"), height);
        descriptor.putEnumerated(s2t("horizontal"), s2t("horizontalLocation"), c2t("Cntr"));
        descriptor.putEnumerated(s2t("vertical"), s2t("verticalLocation"), c2t("Cntr"));
        descriptor.putEnumerated(s2t("canvasExtensionColorType"), s2t("canvasExtensionColorType"), s2t("foregroundColor"));
        executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
    }

    // Restore the ruler units
    app.preferences.rulerUnits = savedRuler;

}

function addColorFillLayer() {

    getColorpickerColor();

    var fColor = app.foregroundColor;
    var R = fColor.rgb.red.toFixed(2);
    var G = fColor.rgb.green.toFixed(2);
    var B = fColor.rgb.blue.toFixed(2);

    makeFill(R, G, B);

    function makeFill(red, Grn, blue) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var descriptor2 = new ActionDescriptor();
        var descriptor3 = new ActionDescriptor();
        var descriptor4 = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putClass(s2t("contentLayer"));
        descriptor.putReference(c2t("null"), reference);
        descriptor4.putDouble(s2t("red"), red);
        descriptor4.putDouble(c2t("Grn "), Grn);
        descriptor4.putDouble(s2t("blue"), blue);
        descriptor3.putObject(s2t("color"), s2t("RGBColor"), descriptor4);
        descriptor2.putObject(s2t("type"), s2t("solidColorLayer"), descriptor3);
        descriptor.putObject(s2t("using"), s2t("contentLayer"), descriptor2);
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

    function getColorpickerColor() {
        if (app.showColorPicker()) {
            return app.foregroundColor;
        } else {
            return false;
        }
    }
}

function moveLayerRelativeStack(relPos) {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var reference = new ActionReference();
    var reference2 = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(relPos));
    descriptor.putReference(s2t("to"), reference2);
    executeAction(s2t("move"), descriptor, DialogModes.NO);
}

function setForeground() {

    var fColor = app.foregroundColor;
    var R = fColor.rgb.red.toFixed(2);
    var G = fColor.rgb.green.toFixed(2);
    var B = fColor.rgb.blue.toFixed(2);

    getColorpickerColor();

    function getColorpickerColor() {
        if (app.showColorPicker()) {
            return app.foregroundColor;
        } else {
            return false;
        }
    }
}

 

 

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

 

Likes

translate

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 ,
Mar 09, 2021 Mar 09, 2021

Copy link to clipboard

Copied

That sounds great! How do I import a script to create an action though? Never done it that way, I usually just export the action 🤔

Likes

translate

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
Adobe Community Professional ,
Mar 09, 2021 Mar 09, 2021

Copy link to clipboard

Copied

Follow the instructions linked above at my prepression blog. There is no need to record this GUI based script into an action.

 

If you need to batch process many files, then this script would need minor modification to remove the manual GUI steps so that it could be inserted/recorded into an action and used with Batch, Image Processor, Image Processor Pro or Picture Processor scripts.

 

Alternatively the batch processing code could be added into the script so that there is no dependency on actions and other batch scripts,

Likes

translate

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
Adobe Community Professional ,
Mar 09, 2021 Mar 09, 2021

Copy link to clipboard

Copied

You might want to consider using the image's diagonal rather than the width, so that verticals and horizontal are more equal in boarder width.

Likes

translate

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
Adobe Community Professional ,
Mar 10, 2021 Mar 10, 2021

Copy link to clipboard

Copied

Thanks for the suggestion Chuck... Math is not my strong area, do you mean something like this?

 

 

/*

Extend Canvas Border by Percentage of Hypotenuse.jsx
Version 1.0
Stephen Marsh - 2021

Need Action That Makes an Equal-Sized Border for Images With Different Sizes
https://community.adobe.com/t5/photoshop/need-action-that-makes-an-equal-sized-border-for-images-with-different-sizes/td-p/11876979 

Action that uses a percentage of image size in pixel dimensions
https://community.adobe.com/t5/photoshop/action-that-uses-a-percentage-of-image-size-in-pixel-dimensions/m-p/9897687

*/

#target photoshop
app.bringToFront();

// Conditional Background layer check
if (app.activeDocument.activeLayer.isBackgroundLayer) {
    setForeground();
    addBorder();
}
// Otherwise run on layered files
else {
    addBorder();
    addColorFillLayer();
    // "previous" or "next" or "front" or "back"
    moveLayerRelativeStack("back");
}

function addBorder() {

    // Save the current ruler units and set to pixels
    var savedRuler = app.preferences.rulerUnits;
    app.preferences.rulerUnits = Units.PIXELS;

    // Loop the input prompt until a number is entered
    var origInput;
    while (isNaN(origInput = prompt("Enter the border size" + "\n" + "(based on a % of the document's hypotenuse)", "4")));

    // Test if cancel returns null, then terminate the script
    if (origInput === null) {
        alert('Script cancelled!');
        return
    }

    // Test if an empty string is returned, then terminate the script
    if (origInput === "") {
        alert('A value was not entered, script cancelled!');
        return
    }

    // Convert decimal input to integer
    var borderSize = parseInt(origInput);

    // Border size value in pixels
    var doc = app.activeDocument;
    var docWidth = doc.width.value;
    var docHeight = doc.height.value;
    // Use the hypotenuse for the basis of the frame size
    var hypot = Math.sqrt(docWidth * docWidth + docHeight * docHeight);
    var canvasExtension = borderSize / 100 * hypot;
    // Resize canvas - relative width & height
    extendCanvasRelative(true, canvasExtension, canvasExtension);

    function extendCanvasRelative(relative, width, height) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        descriptor.putBoolean(s2t("relative"), relative);
        descriptor.putUnitDouble(s2t("width"), s2t("pixelsUnit"), width);
        descriptor.putUnitDouble(s2t("height"), s2t("pixelsUnit"), height);
        descriptor.putEnumerated(s2t("horizontal"), s2t("horizontalLocation"), c2t("Cntr"));
        descriptor.putEnumerated(s2t("vertical"), s2t("verticalLocation"), c2t("Cntr"));
        descriptor.putEnumerated(s2t("canvasExtensionColorType"), s2t("canvasExtensionColorType"), s2t("foregroundColor"));
        executeAction(s2t("canvasSize"), descriptor, DialogModes.NO);
    }

    // Restore the ruler units
    app.preferences.rulerUnits = savedRuler;

}

function addColorFillLayer() {

    getColorpickerColor();

    var fColor = app.foregroundColor;
    var R = fColor.rgb.red.toFixed(2);
    var G = fColor.rgb.green.toFixed(2);
    var B = fColor.rgb.blue.toFixed(2);

    makeFill(R, G, B);

    function makeFill(red, Grn, blue) {
        var c2t = function (s) {
            return app.charIDToTypeID(s);
        };
        var s2t = function (s) {
            return app.stringIDToTypeID(s);
        };
        var descriptor = new ActionDescriptor();
        var descriptor2 = new ActionDescriptor();
        var descriptor3 = new ActionDescriptor();
        var descriptor4 = new ActionDescriptor();
        var reference = new ActionReference();
        reference.putClass(s2t("contentLayer"));
        descriptor.putReference(c2t("null"), reference);
        descriptor4.putDouble(s2t("red"), red);
        descriptor4.putDouble(c2t("Grn "), Grn);
        descriptor4.putDouble(s2t("blue"), blue);
        descriptor3.putObject(s2t("color"), s2t("RGBColor"), descriptor4);
        descriptor2.putObject(s2t("type"), s2t("solidColorLayer"), descriptor3);
        descriptor.putObject(s2t("using"), s2t("contentLayer"), descriptor2);
        executeAction(s2t("make"), descriptor, DialogModes.NO);
    }

    function getColorpickerColor() {
        if (app.showColorPicker()) {
            return app.foregroundColor;
        } else {
            return false;
        }
    }
}

function moveLayerRelativeStack(relPos) {
    var c2t = function (s) {
        return app.charIDToTypeID(s);
    };
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var reference = new ActionReference();
    var reference2 = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(c2t("null"), reference);
    reference2.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(relPos));
    descriptor.putReference(s2t("to"), reference2);
    executeAction(s2t("move"), descriptor, DialogModes.NO);
}

function setForeground() {

    var fColor = app.foregroundColor;
    var R = fColor.rgb.red.toFixed(2);
    var G = fColor.rgb.green.toFixed(2);
    var B = fColor.rgb.blue.toFixed(2);

    getColorpickerColor();

    function getColorpickerColor() {
        if (app.showColorPicker()) {
            return app.foregroundColor;
        } else {
            return false;
        }
    }
}

 

 

Likes

translate

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
Adobe Community Professional ,
Mar 10, 2021 Mar 10, 2021

Copy link to clipboard

Copied

Yes, I think you got it using the hypotenuse formula. 

Likes

translate

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 ,
Mar 10, 2021 Mar 10, 2021

Copy link to clipboard

Copied

Thank you Stephen and Chuck! Really appreciate the help ❤️ this will be very benefial for my work!

Likes

translate

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
Adobe Community Professional ,
Mar 11, 2021 Mar 11, 2021

Copy link to clipboard

Copied

I am glad that you are happy, so thanks for the thanks.

 

I am a little mystified to tell you the truth... Images may potentially have different pixel widths, heights and diagonals between them all. Therefore each and every border will potentially be different sizes, leading to inconsistent thicknesses when using a % of the doc width or height or hypotenuse or area.

 

Therefore I would have thought that simply basing the border off of a fixed absolute pixel value would be best for consistency. If all of your images are the same size from the same camera, then the % based method would lead to a consistent result.

 

Curious minds need to know why...

Likes

translate

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