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

Script to input and select and move layers based on the input

Explorer ,
Dec 31, 2023 Dec 31, 2023

Copy link to clipboard

Copied

I'm not entirely sure of the scope of what's possible but I'm trying to do the following:

Pretext: I have 52 layers named a1 to z1 and also a2 to z2. Each layer has a letter corrseponding to its name. A2 is just a different letter A. The intention is to input a name and generate that name based on the text. I'm planning to print out peoples names that they input. But I don't want to manually sort out each name and each layer on every single order, and since print on demand sites wouldn't allow me to upload 52 pictures, sort and print based on someone's input I would have to at least somewhat do this normally. The name would display based one 1 then 2 then 1 then 2.

for example inputting ADAM, would select layer A1 then move, D2 then move, A2 then move, M1 then move. This is how I envision it, let me know if I'm on the right track please:

  1. Upon clicking action input a name.
  2. Append a 1 corresponding to the first letter of that input and select that layer,
  3. Move layer.
  4. Check for input length.
  5. if more than 1, select the next letter in the input and append a 2,
  6. Move layer,
  7. Continue to input length finishes.

 

to simplify id set up each position from one to ten and just select that as a position based on the input length in the sequencer.

 

Can this be done in photoshop?

TOPICS
Actions and scripting

Views

1.1K

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 2 Correct answers

Community Expert , Jan 01, 2024 Jan 01, 2024

It will take time and effort to create automation for such a task. The investment in time and effort has to be balanced against the time and effort of doing this manually for the volume of orders received.

 

A different approach would be to create a separate square canvas file for each letter in the alphabet (all using the same canvas size and common baseline, same pixel size and resolution etc). 

 

A script could open each required letter and stack the files horizontally to create a word.

 

Thi

...

Votes

Translate

Translate
Community Expert , Jan 03, 2024 Jan 03, 2024

I have no access to the files on the onedrive server so I cannot test with them. 

With a simple test file (with layers only for »a« through »f«) I was able to use the Script below to get an Array of Arrays (containing the Layer’s name, the index [which can be used to address/select the layer], the bounds [which can be used to calculate the necessary offsets]) in which the layers starting with the intended letter are being »rotated« (see the multiple »e«s for example). 

Screenshot 2024-01-03 at 15.30.06.pngScreenshot 2024-01-03 at 15.31.49.png

 

// 2023, use it at your
...

Votes

Translate

Translate
Adobe
Explorer ,
Dec 31, 2023 Dec 31, 2023

Copy link to clipboard

Copied

I'd also need a check to see if an A (or other letter has been selected before) and if so select the next A, which would be A2 instead of A1

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 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

A Photoshop Action cannot do that by itself but a Script could automate such an operation. 

But have you thought the issue through? Will the target positions vary depending on the width of the Layers/Letters (essentially: Is a »W« exactly as wide as an »I«?)? Are the Layers sharp-edges or do they have soft edges or »sprinkles«? 

 

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible? 

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
Explorer ,
Jan 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

Thanks for the reply! Evert letter is massive but in the same 1:1 aspect ratio.

It is a problem I have thought about by just offering a larger canvas if the letter count is past 5.

Attached is how it looks.

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 02, 2024 Jan 02, 2024

Copy link to clipboard

Copied

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible?

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 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

Perhaps you could post before/after screenshots or provide sample PSD and input files.

 

There may be a different or better way to do things.

 

Have you looked into Photoshop Variables (aka: data driven graphics):

 

https://helpx.adobe.com/au/photoshop/using/creating-data-driven-graphics.html

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
Explorer ,
Jan 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

I have not yet but please see the following download links for the short (5 characters and below, and long 5-12).

 SHort:

https://1drv.ms/u/s!Aoh-V2KmRnV1gZgf5oTEH6bxy4o7XA?e=jvMgHg

Long:

https://1drv.ms/u/s!Aoh-V2KmRnV1gZgeK5HwQfleix3X3Q?e=rTIG8H

 

I've managed to find a print provider that can print long and thin but at the moment my images are 20cm x 60cm for short and 30cm x 90cm that most providers can provide.

I did think there might be a different and better way to do things.

 The example ChatGPT gave me was like:

 

// Sample Photoshop Script for Layer Selection

// Function to select a layer by name
function selectLayer(layerName) {
    var layer = app.activeDocument.layers.getByName(layerName);
    layer.visible = true;
    app.activeDocument.activeLayer = layer;
}

// Function to move the selected layer
function moveLayer(position) {
    app.activeDocument.activeLayer.translate(position[0], position[1]);
}

// Function to process input name
function processName(inputName) {
    for (var i = 0; i < inputName.length; i++) {
        var currentLetter = inputName[i].toLowerCase();
        var layerName = currentLetter + (i % 2 + 1); // Alternating between 1 and 2
        selectLayer(layerName);

        // Adjust these values based on your layout
        var positionX = i * 50; // Adjust as needed
        var positionY = 0; // Adjust as needed
        moveLayer([positionX, positionY]);
    }
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    app.activeDocument.suspendHistory("Process Name", "processName('" + userInput + "');");
}

 

 

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 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

And as with type in general some combinations of letters (like »VA« for example) can result in an uneven appearance if they are not properly spaced/kerned. 

Do you intend to give the results a »go-over« anyway or do you expect full automatization? 

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
Explorer ,
Jan 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

Since each letter is within a square 1:1 profile I think it's not a problem in this case but I fully expect to at least quality check each one. The idea is to reduce the amount of work but I'm not opposed to little touch ups if required, especially as doing the whole thing by hand from scratch would be a pain.

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 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

OK, so you wish to create file with a customer's first and last name, using a custom letter for each letter in their name. This has to be at a high resolution for print output, so the following suggestion may have limitations...

 

One can create custom colour raster fonts with each letter being an image.

 

The following is commercial software, it mentions supporting bitmap fonts:

 

https://www.fontself.com/features

 

There are other alternatives if you search the web.

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 01, 2024 Jan 01, 2024

Copy link to clipboard

Copied

It will take time and effort to create automation for such a task. The investment in time and effort has to be balanced against the time and effort of doing this manually for the volume of orders received.

 

A different approach would be to create a separate square canvas file for each letter in the alphabet (all using the same canvas size and common baseline, same pixel size and resolution etc). 

 

A script could open each required letter and stack the files horizontally to create a word.

 

This could be very basic, as in you manually select the required letters and the script would just make the word. You would have to manually account for cases where there was more than one of the same letter, either by manually fixing the stacked layered file or having multiple copies of the same letter file where you could then select them multiple times as needed.

 

Another approach could be a script using a text file as a list of input files, placing each image as required to the right of the previous file (this would be more automated than the previous example).

 

A script could read a text file where the name was "bob", it could then split each letter to a new separate line, including adding text to create a fixed image source path, i.e.:

 

"~/Desktop/Illuminated Letters/b.psd"

"~/Desktop/Illuminated Letters/o.psd"

"~/Desktop/Illuminated Letters/b.psd"

 

The script would then open and horizontally stack each file to create the word.

 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

That last bit was the closest to my solution, so I've marked you also as correct answer. Thank you.

 

Now i've got to figure out how to automate the ordering after its created without having to manually place an order each time if the worst (and I guess best) happens and I get a bunch of orders at once. It's a shame order and print services don't offer this already.

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 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

If I remember correctly a Script can evaluate the text in the clipboard, so you could create a version that offers no dialog but simply uses that. 

Or do you need to add more functionality like selecting from several different letter-options? 

How do the orders arrive – text in a mail? 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

So the intention is to use a print on demand service. Normally within shopify or etsy you would create "customisable text" but this is just... normal text times new roman or something, not custom different letters.

You also can't upload all 60 ish layers as super large res pictures and then select the ones required to be printed via the orderers input and move them all into one coherent canvas. I haven't yet messaged the services to see if that's something they can provide but I'm certain it's likely to be alot of work on their end if it was.

So I thought I'd cut out the brunt of the work which is creating the name itself. Now I just open the photosop file, run the script, name is created. Then I manually upload that to the print on demand service and put in the address of the person it needs to be sent too. That second part i'd really like to be auto but I just can't think of a way.

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

Copy link to clipboard

Copied

I have no access to the files on the onedrive server so I cannot test with them. 

With a simple test file (with layers only for »a« through »f«) I was able to use the Script below to get an Array of Arrays (containing the Layer’s name, the index [which can be used to address/select the layer], the bounds [which can be used to calculate the necessary offsets]) in which the layers starting with the intended letter are being »rotated« (see the multiple »e«s for example). 

Screenshot 2024-01-03 at 15.30.06.pngScreenshot 2024-01-03 at 15.31.49.png

 

// 2023, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = activeDocument;
var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
////////////////////////////////////
var theString = "badebefefe";
var theLayers = collectLayersBounds ();
theLayers.sort();
var theRegExp = /^\D\d$/i;
// create arrays sorted by initial letter;
var theArrays = new Array;
for (var m = 0; m < theLayers.length; m++) {
    var thisOne = theLayers[m];
    var theCheck = false;
    if (thisOne[0].match(theRegExp) != null) {
        var theLetter = String(thisOne[0].match(/^\D/i));
        for (var n = 0; n < theArrays.length; n++) {
            if (theArrays[n][0][0][0] == theLetter) {
                theArrays[n].push(thisOne);
                var theCheck = true
            }
        };
        if (theCheck != true) {theArrays.push([thisOne])};
    }
};
// check string against array;
var theResult = new Array;
for (var o = 0; o < theString.length; o++) {
    var thisOne = theString[o];
    for (var p = 0; p < theArrays.length; p++) {
        if (theArrays[p][0][0][0].match(new RegExp (thisOne, "i")) != null) {
            theResult.push (theArrays[p][0])
            theArrays[p].push(theArrays[p].splice(0,1));
        }
    };
};
alert (theResult.join("\n"));
////////////////////////////////////
app.preferences.rulerUnits = originalRulerUnits;
};
////// collect layers //////
function collectLayersBounds () {
// get number of layers;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theBounds = layerDesc.getObjectValue(stringIDToTypeID("bounds"));
var theseBounds = [theBounds.getUnitDoubleValue(stringIDToTypeID("left")), theBounds.getUnitDoubleValue(stringIDToTypeID("top")), theBounds.getUnitDoubleValue(stringIDToTypeID("right")), theBounds.getUnitDoubleValue(stringIDToTypeID("bottom"))];
theLayers.push([theName, theID, theseBounds])
};
}
catch (e) {};
};
return theLayers
};

 

 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

I ended up creating the script myself but this is the closest to the answer required and helped me further optimise the script I was using. Thanks alot.

Just for info, mine asks for input, finds the first letter, shifts the next letters to the right of the first letter to create the name.

It has a counter for how many of the same letters have appeared to change to another letter, and if more than 2 duplicate letters have apppeared move onto the 3rd and 4th letter in that sequence.

Outside of that script it checks to if the last letter was not a duplicate and move to the second variation, or first, so that each letter uses a different variation and is likely not to have the same variation next to each other in the name outside of a duplicated letter repeat.

the script then crops the canvas to fit the letters perfectly.

The only issue i'm having is that when trying to align all letters after canvas cropping photoshop hangs or crashes but i'm sure I'll solve that with more testing.

 

Thanks alot for yours and everyone elses 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 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

How do you align the Layers in the code? 

Move the Layers based on their bounds or select them all and use the AM-code for actual Align-commands or …? 

Do you remove the superfluous letter-layers at some point? 

 

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible? 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

So I have layers A1-Z1, A2-Z2, then I have popular letters going A3, A4, A5 corresponding to the letter which the code will select.

 

I'll post my code:

// Function to select a layer by name
function selectLayerByName(layerName) {
    var layer = app.activeDocument.layers.getByName(layerName);
    layer.visible = true;
    app.activeDocument.activeLayer = layer;
}

// Function to move the selected layer
function moveLayer(position) {
    app.activeDocument.activeLayer.translate(position[0], position[1]);
}

// Function to resize the canvas based on input length
function resizeCanvas(inputLength) {
    var canvasWidth = 1804 * inputLength; // Adjust as needed
    var canvasHeight = 2000; // Adjust as needed
    app.activeDocument.resizeCanvas(canvasWidth, canvasHeight, AnchorPosition.TOPLEFT);
}

// Function to process input name
function processName(inputName) {
    var shiftAmount = 1804; // Adjust this value based on your preference
    var layerMap = {}; // Map to track the last digit used for each letter
    var currentDigit = 1; // Initialize the currentDigit to 1

    // Resize the canvas based on the input length
    resizeCanvas(inputName.length);

    // Adjust starting position for the first letter
    var firstLetterPositionX = (inputName.length - 1) * shiftAmount * 0.5; // Centered on the left side

    for (var i = 0; i < inputName.length; i++) {
        var currentLetter = inputName[i].toUpperCase();
        var layerName;

        // Check if the letter has been used before
        if (layerMap.hasOwnProperty(currentLetter)) {
            // If the letter has been used before, use the last digit
            currentDigit = layerMap[currentLetter];
        } else {
            // If the letter is used for the first time, set the count to 1
            layerMap[currentLetter] = currentDigit;
            // Use the alternating logic between 1 and 2
            currentDigit = 3 - currentDigit;
        }

        layerName = currentLetter + layerMap[currentLetter];
        layerMap[currentLetter]++;

        selectLayerByName(layerName);

        // Adjust these values based on your layout
        var positionX = firstLetterPositionX + i * shiftAmount; // Adjust as needed
        var positionY = 0; // Adjust as needed
        moveLayer([positionX, positionY]);
    }
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    app.activeDocument.suspendHistory("Process Name", "processName('" + userInput + "');");
}

 

This gives for the input "testy" gives: Testy.png

At the moment I need to Control + Alt + A to select all layers then move the first one to the left centered vertically like this:

Testy moved.png

 

I tried to do this with the following script:

// Function to select a layer by name
function selectLayerByName(layerName) {
    var layer = app.activeDocument.layers.getByName(layerName);
    layer.visible = true;
    app.activeDocument.activeLayer = layer;
}

// Function to move the selected layer
function moveLayer(position) {
    app.activeDocument.activeLayer.translate(position[0], position[1]);
}

// Function to resize the canvas based on input length
function resizeCanvas(inputLength) {
    var canvasWidth = 1804 * inputLength; // Adjust as needed
    var canvasHeight = 2000; // Adjust as needed
    app.activeDocument.resizeCanvas(canvasWidth, canvasHeight, AnchorPosition.TOPLEFT);
}

// Function to process input name
function processName(inputName) {
    var shiftAmount = 1804; // Adjust this value based on your preference
    var layerMap = {}; // Map to track the last digit used for each letter
    var currentDigit = 1; // Initialize the currentDigit to 1

    // Resize the canvas based on the input length
    resizeCanvas(inputName.length);

    // Adjust starting position for the first letter
    var firstLetterPositionX = (inputName.length - 1) * shiftAmount * 0.5; // Centered on the left side

    for (var i = 0; i < inputName.length; i++) {
        var currentLetter = inputName[i].toUpperCase();
        var layerName;

        // Check if the letter has been used before
        if (layerMap.hasOwnProperty(currentLetter)) {
            // If the letter has been used before, use the last digit
            currentDigit = layerMap[currentLetter];
        } else {
            // If the letter is used for the first time, set the count to 1
            layerMap[currentLetter] = currentDigit;
            // Use the alternating logic between 1 and 2
            currentDigit = 3 - currentDigit;
        }

        layerName = currentLetter + layerMap[currentLetter];
        layerMap[currentLetter]++;

        selectLayerByName(layerName);

        // Adjust these values based on your layout
        var positionX = firstLetterPositionX + i * shiftAmount; // Adjust as needed
        var positionY = 0; // Adjust as needed
        moveLayer([positionX, positionY]);
    }
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    app.activeDocument.suspendHistory("Process Name", "processName('" + userInput + "');");
  
    // Function to move all visible layers by a specified amount
    function moveAllVisibleLayers(leftOffset, verticalOffset) {
        var visibleLayers = [];

        // Collect all visible layers
        for (var i = 0; i < app.activeDocument.layers.length; i++) {
            var layer = app.activeDocument.layers[i];
            if (layer.visible) {
                visibleLayers.push(layer);
            }
        }

        // Move all visible layers
        for (var i = 0; i < visibleLayers.length; i++) {
            visibleLayers[i].translate(leftOffset, verticalOffset);
        }
    }

    // Move all visible layers after processing the name
    var leftOffset = -500; // Adjust as needed
    var verticalOffset = 0; // Adjust as needed
    moveAllVisibleLayers(leftOffset, verticalOffset);
}

 

This comes up with the error:

Testy problem.png

And then terminates.

I've tried to do this without relying on the translate method:

// Function to process input name
function processName(inputName) {
    var shiftAmount = 1804; // Adjust this value based on your preference

    try {
        // Resize the canvas based on the input length
        var canvasWidth = shiftAmount * inputName.length; // Adjust as needed
        var canvasHeight = 2000; // Adjust as needed
        app.activeDocument.resizeCanvas(canvasWidth, canvasHeight, AnchorPosition.TOPLEFT);

        // Move layers to the left and center vertically
        var layers = app.activeDocument.artLayers;
        var topmostLayer = layers[layers.length - 1];
        var centerY = canvasHeight * 0.5;
        var verticalOffset = centerY - topmostLayer.bounds[1];

        for (var i = 0; i < layers.length; i++) {
            var layer = layers[i];
            var leftOffset = i * shiftAmount;
            layer.translate(leftOffset, verticalOffset);
        }
    } catch (error) {
        alert("An error occurred: " + error);
    }
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    processName(userInput);
}

This makes photoshop either continually load or crash altogether.

I added delays because maybe the image hasn't finished processing and this didn't solve the issue.

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

Bah the error didn't come out very large it said: "The command transform is not currently available"

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 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

Instead of moving the Layers wouldn’t it be easier to use Reveal All and Trim (respectively the corresponding AM-code)? 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

Let me give that a try, I think you're right, my current solution is seriously inefficient.

// Function to select a layer by name
function selectLayerByName(layerName) {
    var layer = app.activeDocument.layers.getByName(layerName);
    layer.visible = true;
    app.activeDocument.activeLayer = layer;
}

// Function to reveal all and trim
function revealAllAndTrim() {
    app.activeDocument.revealAll();
    app.activeDocument.trim(TrimType.TRANSPARENT, true, true, true, true);
}

// Function to process input name
function processName(inputName) {
    var shiftAmount = 1804; // Adjust this value based on your preference
    var layerMap = {}; // Map to track the last digit used for each letter
    var currentDigit = 1; // Initialize the currentDigit to 1

    // Resize the canvas based on the input length
    app.activeDocument.resizeCanvas(1804 * inputName.length, 2000, AnchorPosition.TOPLEFT);

    // Adjust starting position for the first letter
    var firstLetterPositionX = (inputName.length - 1) * shiftAmount * 0.5; // Centered on the left side

    for (var i = 0; i < inputName.length; i++) {
        var currentLetter = inputName[i].toUpperCase();
        var layerName;

        // Check if the letter has been used before
        if (layerMap.hasOwnProperty(currentLetter)) {
            // If the letter has been used before, use the last digit
            currentDigit = layerMap[currentLetter];
        } else {
            // If the letter is used for the first time, set the count to 1
            layerMap[currentLetter] = currentDigit;
            // Use the alternating logic between 1 and 2
            currentDigit = 3 - currentDigit;
        }

        layerName = currentLetter + layerMap[currentLetter];
        layerMap[currentLetter]++;

        selectLayerByName(layerName);

        // Adjust these values based on your layout
        var positionX = firstLetterPositionX + i * shiftAmount; // Adjust as needed
        var positionY = 0; // Adjust as needed
        app.activeDocument.activeLayer.translate(positionX, positionY);
    }

    // After processing all layers, reveal all and trim
    revealAllAndTrim();
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    app.activeDocument.suspendHistory("Process Name", "processName('" + userInput + "');");
}

Okay this worked but the processing for it was, after the second prompt for trim, about a minute long, doesn't sound long but if I have 50 to do, it could be. Any way you can think of to speed it up? It might be because the layers are so large and that might be something I can't really get around.

 

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 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

You are using DOM code; AM code usually runs »somewhat« to »a lot« faster. 

Another recommendation: Hiding the Panels at the beginning of a Script and revealing them again at the end. 

Might not seem like much of an influence, but the previews being generated for the Channels and Layers Panel for example seem to take some time. 

app.togglePalettes();

 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

So I converted to AM script and I get an error, this is what I'm running:

 

// Function to select a layer by name
function selectLayerByName(layerName) {
    var layer = app.activeDocument.layers.getByName(layerName);
    layer.visible = true;
    app.activeDocument.activeLayer = layer;
}

// Function to trim transparent areas using AM code
function trimTransparent() {
    var idtrim = stringIDToTypeID("trim");
    var desc29 = new ActionDescriptor();
    var idtrimBasedOn = stringIDToTypeID("trimBasedOn");
    var idTrns = charIDToTypeID("Trns");
    desc29.putEnumerated(idtrimBasedOn, idtrimBasedOn, idTrns);
    var idtrim = stringIDToTypeID("trim");
    desc29.putBoolean(idtrim, true);
    executeAction(idtrim, desc29, DialogModes.NO);
}

// Function to process input name
function processName(inputName) {
    var shiftAmount = 1804; // Adjust this value based on your preference
    var layerMap = {}; // Map to track the last digit used for each letter
    var currentDigit = 1; // Initialize the currentDigit to 1

    // Resize the canvas based on the input length using AM code
    var idCnvS = charIDToTypeID("CnvS");
    var desc6 = new ActionDescriptor();
    var idWdth = charIDToTypeID("Wdth");
    var idRlt = charIDToTypeID("#Rlt");
    desc6.putUnitDouble(idWdth, idRlt, 1804 * inputName.length);
    var idHght = charIDToTypeID("Hght");
    var idRlt = charIDToTypeID("#Rlt");
    desc6.putUnitDouble(idHght, idRlt, 2000);
    var idHrzn = charIDToTypeID("Hrzn");
    var idRlt = charIDToTypeID("#Rlt");
    desc6.putUnitDouble(idHrzn, idRlt, 0);
    var idVrtc = charIDToTypeID("Vrtc");
    var idRlt = charIDToTypeID("#Rlt");
    desc6.putUnitDouble(idVrtc, idRlt, 0);
    executeAction(idCnvS, desc6, DialogModes.NO);

    // Adjust starting position for the first letter
    var firstLetterPositionX = (inputName.length - 1) * shiftAmount * 0.5; // Centered on the left side

    for (var i = 0; i < inputName.length; i++) {
        var currentLetter = inputName[i].toUpperCase();
        var layerName;

        // Check if the letter has been used before
        if (layerMap.hasOwnProperty(currentLetter)) {
            // If the letter has been used before, use the last digit
            currentDigit = layerMap[currentLetter];
        } else {
            // If the letter is used for the first time, set the count to 1
            layerMap[currentLetter] = currentDigit;
            // Use the alternating logic between 1 and 2
            currentDigit = 3 - currentDigit;
        }

        layerName = currentLetter + layerMap[currentLetter];
        layerMap[currentLetter]++;

        selectLayerByName(layerName);

        // Adjust these values based on your layout using AM code
        var idTrnf = charIDToTypeID("Trnf");
        var desc14 = new ActionDescriptor();
        var idHrzn = charIDToTypeID("Hrzn");
        var idPxl = charIDToTypeID("#Pxl");
        desc14.putUnitDouble(idHrzn, idPxl, firstLetterPositionX + i * shiftAmount);
        var idVrtc = charIDToTypeID("Vrtc");
        var idPxl = charIDToTypeID("#Pxl");
        desc14.putUnitDouble(idVrtc, idPxl, 0);
        executeAction(idTrnf, desc14, DialogModes.NO);
    }

    // After processing all layers, trim transparent areas using AM code
    trimTransparent();
}

// Example usage
var userInput = prompt("Enter a name:", "");
if (userInput) {
    app.activeDocument.suspendHistory("Process Name", "processName('" + userInput + "');");
}

 

 
This comes up with the error 8800: General photoshop error occured. This functionality may not be available in this version of photoshop. could not complete the command because of a program error. Line: 41 -> executeAction(idCnVs, desc6, DialogModes.NO);
 
Any way to diagnose that? The only way I've be able to overcome this is by adding DOM code for the trim. My version is the latest, what could I do?

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 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

How did you get the AM code? Did you record it yourself? 

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible? 

trimTransparent();

////// trim //////
function trimTransparent () {
// trim transparent;
var desc232 = new ActionDescriptor();
desc232.putEnumerated(stringIDToTypeID( "trimBasedOn" ), stringIDToTypeID( "trimBasedOn" ), stringIDToTypeID( "transparency" ));
desc232.putBoolean( stringIDToTypeID( "top" ), true );
desc232.putBoolean( stringIDToTypeID( "bottom" ), true );
desc232.putBoolean( stringIDToTypeID( "left" ), true );
desc232.putBoolean( stringIDToTypeID( "right" ), true );
executeAction( stringIDToTypeID( "trim" ), desc232, DialogModes.NO );
};

 

The trimming part only runs once, so the gains will be less relevant anyway than the moving for example, which happens more often. 

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
Explorer ,
Jan 04, 2024 Jan 04, 2024

Copy link to clipboard

Copied

I've given up, taking too much time to diagnose and re-write, even your script to trim on it's own is coming up with a general error. I've paired this with an action to run the script and moved all layers manually, it works instantly. Glad I got it sorted before going back to my 12 hour shift for my actual job lol. Thanks for the 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