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

【Help】Convert a layer group to an artboard

New Here ,
Apr 13, 2024 Apr 13, 2024

Copy link to clipboard

Copied

A.png

I have a batch of PSD files, some of which contain multiple layer groups as shown in the above image. The number of layer groups in each file is uncertain. I've written a script using ChatGPT and Claude to place each layer group on a canvas, with the canvas size being the same as the original file. However, I can't seem to get it to run successfully. The desired outcome is as shown in the image.

B.png

 

// Check if there are any Post layer groups
function hasPostGroups() {
var doc = app.activeDocument;
for (var i = 1; i <= doc.layerSets.length; i++) {
var layerSet = doc.layerSets[i - 1];
if (layerSet.name.indexOf("Post") === 0) {
return true;
}
}
return false;
}

// Create artboards
function createArtboards(num) {
var doc = app.activeDocument;
for (var i = 0; i < num; i++) {
var artboard = doc.artboards.add(doc.artboards[0].artboardRect);
artboard.name = "Artboard " + (i + 1);
}
}

// Move Post layer groups to corresponding artboards
function movePostGroupsToArtboards() {
var doc = app.activeDocument;
var artboardIndex = 0;
for (var i = 1; i <= doc.layerSets.length; i++) {
var layerSet = doc.layerSets[i - 1];
if (layerSet.name.indexOf("Post") === 0) {
var artboard = doc.artboards[artboardIndex];
var artboardRect = artboard.artboardRect;
var bounds = layerSet.bounds;
var offsetX = artboardRect[0] - bounds[0].value;
var offsetY = artboardRect[1] - bounds[1].value;
layerSet.translate(offsetX, offsetY);
artboardIndex++;
}
}
}

// Main function
function main() {
if (!hasPostGroups()) {
alert("There are no Post layer groups in the current document, no further action will be taken.");
return;
}

var numPostGroups = app.activeDocument.layerSets.length;
createArtboards(numPostGroups);
movePostGroupsToArtboards();

alert("Operation completed!");
}

// Execute the main function
main();

 

TOPICS
Actions and scripting , Windows

Views

187

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 Expert ,
Apr 14, 2024 Apr 14, 2024

Copy link to clipboard

Copied

@Liu254468142lhe 

 

A basic conversion of all root/top-level groups to artboards will simply stack each artboard, one on top of the other*. This script is a bit of a cheat, but it works for me. Extra code could be added to check if the layer group contained "Post" in its name:

 

/* 
All Root-Top-Level Groups to Artboards.jsx
v1.0 15th April 2024, Stephen Marsh
https://community.adobe.com/t5/photoshop-ecosystem-discussions/help-convert-a-layer-group-to-an-artboard/td-p/14552904
NOTE: This script makes use of features found in later versions of Photoshop. Tested in version 2024 and 2021, errors may occur in earlier versions.
*/

try {

    ///// Pre-loop /////

    // Ensure that a layer is selected before starting the loop
    app.activeDocument.activeLayer = app.activeDocument.activeLayer.layers[0];

    ///// Loop over the root/top-level layer sets /////
    for (var i = 0; i < activeDocument.layerSets.length; i++) {

        activeDocument.activeLayer = activeDocument.layers[i];
        if (isGroup() === true) {
            groupToArtboard();
        }

        function isGroup() {
            // modified from a script by greless with hints from jazz-y!
            // returns true or false
                var r = new ActionReference();
                r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
                var options = executeActionGet(r);
                return options.hasKey(stringIDToTypeID('layerSection')) && !options.hasKey(stringIDToTypeID('framedGroup')) && !options.hasKey(stringIDToTypeID('artboard')); // test for the required key
        }

        function groupToArtboard() {
            // Convert the group to a SO to "safely isolate it" for the artboard conversion
            executeAction(stringIDToTypeID("newPlacedLayer"), undefined, DialogModes.NO);
            // Edit the SO
            executeAction(stringIDToTypeID("placedLayerEditContents"), undefined, DialogModes.NO);
            // Convert the group to an artboard
            var idselect = stringIDToTypeID("select");
            var desc751 = new ActionDescriptor();
            var idnull = stringIDToTypeID("null");
            var ref90 = new ActionReference();
            var idmenuItemClass = stringIDToTypeID("menuItemClass");
            var idmenuItemType = stringIDToTypeID("menuItemType");
            var idartboardFromLayersEvent = stringIDToTypeID("artboardFromLayersEvent");
            ref90.putEnumerated(idmenuItemClass, idmenuItemType, idartboardFromLayersEvent);
            desc751.putReference(idnull, ref90);
            executeAction(idselect, desc751, DialogModes.NO);
            // Close the SO saving changes
            app.activeDocument.close(SaveOptions.SAVECHANGES);
            // Convert the SO to layers
            var idselect = stringIDToTypeID("select");
            var desc816 = new ActionDescriptor();
            var idnull = stringIDToTypeID("null");
            var ref95 = new ActionReference();
            var idmenuItemClass = stringIDToTypeID("menuItemClass");
            var idmenuItemType = stringIDToTypeID("menuItemType");
            var idplacedLayerConvertToLayers = stringIDToTypeID("placedLayerConvertToLayers");
            ref95.putEnumerated(idmenuItemClass, idmenuItemType, idplacedLayerConvertToLayers);
            desc816.putReference(idnull, ref95);
            executeAction(idselect, desc816, DialogModes.NO);

        }
    }

    ///// Post-loop /////

    // Select all layers
    app.runMenuItem(stringIDToTypeID('selectAllLayers'));

    // Unlock the nested artboards
    var s2t = function (s) {
        return app.stringIDToTypeID(s);
    };
    var descriptor = new ActionDescriptor();
    var descriptor2 = new ActionDescriptor();
    var reference = new ActionReference();
    reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
    descriptor.putReference(s2t("null"), reference);
    descriptor2.putBoolean(s2t("protectNone"), true);
    descriptor.putObject(s2t("layerLocking"), s2t("layerLocking"), descriptor2);
    executeAction(s2t("applyLocking"), descriptor, DialogModes.NO);

    // Deselect all layers
    app.runMenuItem(stringIDToTypeID('selectNoLayers'));

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

 

* I find it hard to script the distribution and gap of artboards (horizontally, vertically, in a grid/array etc). I am not aware of any scripts that can auto-arrange and or space out all artboards into such a layout (such a script would be a great tool to have, I have never been able to get the distribute artboards feature to work for this task).

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

Thank you very much for your reply. After searching for relevant information, I modified the script. Now the script can successfully create multiple artboards and arrange them neatly. However, I am unable to move layer groups like Post 2 to their corresponding artboards.

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

// Function to get the count of layer groups starting with "Post "
function getPostLayerGroupCount() {
var PostGroupCount = 0;
var layers = app.activeDocument.layers;
for (var i = 0; i < layers.length; i++) {
if (layers[i].typename == "LayerSet" && layers[i].name.indexOf("Post ") === 0) {
PostGroupCount++;
}
}
return PostGroupCount;
}

// Function to get the file size
function getFileSize() {
var width = app.activeDocument.width.value;
var height = app.activeDocument.height.value;
return {width: width, height: height};
}

// Function to create artboards
function createArtboards(PostGroupCount, fileSize) {
var interval = 100; // Interval between artboards
var startX = 0;
var startY = 0;
for (var i = 0; i < PostGroupCount; i++) {
var name = "Artboard " + (i + 1);
var left = startX;
var top = startY;
var right = startX + fileSize.width;
var bottom = startY + fileSize.height;
createArtboard(top, left, bottom, right, name);
startX += fileSize.width + interval; // Update the starting position for the next artboard
}
}

// Function to create a single artboard
function createArtboard(top, left, bottom, right, name) {
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putClass(sTID("artboardSection"));
desc1.putReference(cTID('null'), ref1);
desc1.putString(cTID('Nm '), name);
var desc2 = new ActionDescriptor();
desc2.putDouble(cTID('Top '), top);
desc2.putDouble(cTID('Left'), left);
desc2.putDouble(cTID('Btom'), bottom);
desc2.putDouble(cTID('Rght'), right);
desc1.putObject(sTID("artboardRect"), sTID("classFloatRect"), desc2);
executeAction(sTID('make'), desc1, DialogModes.NO);
}

// Function to move "Post " layer groups to artboards
function movePostGroupToArtboard(PostIndex, artboardIndex) {
var doc = app.activeDocument;
var PostGroupName = "Post " + PostIndex;
var sourceArtboard = doc.layerSets.getByName("Artboard 1");
var destinationArtboard = doc.layerSets.getByName("Artboard " + artboardIndex);
if (sourceArtboard && destinationArtboard) {
var layers = sourceArtboard.layers;
for (var i = 0; i < layers.length; i++) {
if (layers[i].typename == "LayerSet" && layers[i].name == PostGroupName) {
var PostGroup = layers[i];
PostGroup.move(destinationArtboard, ElementPlacement.INSIDE);
break;
}
}
}
}

// Main function
function main() {
var PostGroupCount = getPostLayerGroupCount();
if (PostGroupCount > 0) {
var fileSize = getFileSize();
createArtboards(PostGroupCount, fileSize);

// Move each "Post " layer group to its respective artboard
for (var i = 2; i <= PostGroupCount + 1; i++) { // Start moving from "Post 2" to "Artboard 2"
movePostGroupToArtboard(i, i);
}
}
}

// Execute the main function
main();

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

Copy link to clipboard

Copied

@Liu254468142lhe – Unfortunately the script doesn't run for me, nothing happens.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

This is the script 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
Community Expert ,
Apr 15, 2024 Apr 15, 2024

Copy link to clipboard

Copied

Unfortunately, I get the same result, nothing happens, no artboards are created from the groups and no errors.

Votes

Translate

Translate

Report

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

Copy link to clipboard

Copied

LATEST
#target photoshop

//
// Generated Tue Apr 16 2024 09:24:14 GMT+0800
//

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

//
=
//
function () {
  function step1(enabled, withDialog) {
    if (enabled != undefined && !enabled)
      return;
    var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putName(cTID('Lyr '), "Post 2");
    desc1.putReference(cTID('null'), ref1);
    var ref2 = new ActionReference();
    ref2.putIndex(cTID('Lyr '), 295);
    desc1.putReference(cTID('T   '), ref2);
    desc1.putBoolean(cTID('Adjs'), false);
    desc1.putInteger(cTID('Vrsn'), 5);
    var list1 = new ActionList();
    list1.putInteger(2096);
    desc1.putList(cTID('LyrI'), list1);
    executeAction(sTID('move'), desc1, dialogMode);
  };

  step1();     
};

According to the script code exported using actions above, the rewritten script below cannot correctly obtain the index number of the artboard. Post 2 was moved to the wrong position. How can I obtain the correct index number of the artboard?(PHOTOSHOP 24.0.0)

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };

// Find the index of an artboard
function findArtboardByName(artboardName) {
    var layers = app.activeDocument.layers;
    var found = false;
    for (var i = 0; i < layers.length; i++) {
        if (layers[i].typename === "LayerSet" && layers[i].name === artboardName) {
            alert("Found artboard: " + artboardName + " at index " + (i + 1));
            found = true;
            return i + 1; // Photoshop index starts from 1
        }
    }
    if (!found) {
        alert("Artboard not found: " + artboardName);
    }
    return -1; // Return -1 if not found
}

// Move a layer group to an artboard by its name
function moveGroupToArtboardByName(groupName, artboardName) {
    var artboardIndex = findArtboardByName(artboardName);
    if (artboardIndex === -1) {
        return; // Exit if artboard not found
    }

    var desc = new ActionDescriptor();
    var ref = new ActionReference();
    ref.putName(cTID("Lyr "), groupName);
    desc.putReference(cTID("null"), ref);
    var ref2 = new ActionReference();
    ref2.putIndex(cTID("ArtL"), artboardIndex);
    desc.putReference(cTID("T   "), ref2);
    desc.putBoolean(cTID("Adjs"), false);
    desc.putInteger(cTID("Vrsn"), 5);
    try {
        executeAction(cTID("move"), desc, DialogModes.NO);
        alert("Layer group '" + groupName + "' moved to artboard '" + artboardName + "'");
    } catch (e) {
        alert("Error moving layer group: " + e.toString());
    }
}

// Call the function to move the layer group named "Post 2" to the artboard named "Artboard 2"
moveGroupToArtboardByName("Post 2", "Artboard 2");

 

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