Skip to main content
Participant
April 16, 2024
Answered

Script problem! Help me, please :(

  • April 16, 2024
  • 9 replies
  • 418 views

The code below is working:

But currently it calculates based on the total area of the document, I need it to calculate only the area of the artboard where the layer is located, as I normally work with multiple artboards in a single document.

can anybody help me?


// Get the active layer
var layer = app.activeDocument.activeLayer;

// Gets the dimensions of the canvas/artboard
var artboardWidth = app.activeDocument.width.value;
var artboardHeight = app.activeDocument.height.value;

// Gets the layer dimensions
var layerWidth = layer.bounds[2].value - layer.bounds[0].value;
var layerHeight = layer.bounds[3].value - layer.bounds[1].value;

// Calculates the total area of the screen/artboard
var artboardArea = artboardWidth * artboardHeight;

// Calculate the layer area
var layerArea = layerWidth * layerHeight;

// Calculate the total percentage of the layer
var totalPercentage = (layerArea / artboardArea) * 100;

// Checks if the layer occupies more than 30% of the screen/artboard
if (totalPercentage >= 30) {
alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the screen/artboard. Test passed!");
} else {
alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the canvas/artboard. Increase the layer to pass the test!");
}

 

 

This topic has been closed for replies.
Correct answer Stephen Marsh

@magnos23200120 

 

As the script uses ExtendScript Action Manager code to retrieve the artboard bounds and to check if the layer is an artboard (as opposed to a group), this code may not work in older versions of Photoshop. I have tested in 2021 and 2024:

 

#target photoshop

  // Checks that the active layer is an artboard
  if (isArtboard() === true) {

    alert("Select a layer inside the artboard and run the script again...")

  } else {

    // Check that the current layer is a standard pixel layer
    if (app.activeDocument.activeLayer.typename === "ArtLayer" && app.activeDocument.activeLayer.kind === LayerKind.NORMAL) {

      // Set the ruler units to px, don't assume that they are set to px
      var originalRulerUnits = app.preferences.rulerUnits;
      app.preferences.rulerUnits = Units.PIXELS;

      // Set the original layer as a variable
      var theLayer = app.activeDocument.activeLayer;

      // Traverse the layers until the artboard is selected
      while (isArtboard() === false) {
        app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;
      }

      try {
        // Active Artboard Dimensions, by Rune L-H
        var ref = new ActionReference();
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        var artBoardRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
        var artBoardRectWidth = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("right")) - artBoardRect.getDouble(stringIDToTypeID("left")), "px");
        var artBoardRectHeight = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("bottom")) - artBoardRect.getDouble(stringIDToTypeID("top")), "px");
      } catch (e) {
        alert("The problem could be that the layer is inside of a group..." + "\r" + e + ' ' + e.line);
        
        // Return to the original layer
        app.activeDocument.activeLayer = theLayer;
      }

      // Gets the layer dimensions
      var layerWidth = theLayer.bounds[2].value - theLayer.bounds[0].value;
      var layerHeight = theLayer.bounds[3].value - theLayer.bounds[1].value;

      // Calculates the total area of the screen/artboard
      var artboardArea = artBoardRectWidth.value * artBoardRectHeight.value;

      // Calculate the layer area
      var layerArea = layerWidth * layerHeight;

      // Calculate the total percentage of the layer
      var totalPercentage = (layerArea / artboardArea) * 100;

      // Checks if the layer occupies more than 30% of the screen/artboard
      if (totalPercentage >= 30) {
        alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the screen/artboard. Test passed!");
      } else {
        alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the canvas/artboard. Increase the layer to pass the test!");
      }

      // Return to the original layer
      app.activeDocument.activeLayer = theLayer;

    } else {
      alert("Ensure that a standard pixel layer is selected...");
    }

    // Return the original ruler units
    app.preferences.rulerUnits = originalRulerUnits;

  }


function isArtboard() {
  // modified from a script by greless with hints from jazz-y!
  // returns true or false
  try {
    var d = new ActionDescriptor();
    var r = new ActionReference();
    r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
    var options = executeActionGet(r);
    return options.hasKey(stringIDToTypeID('artboard')); // test for the required key
  } catch (e) {
    alert("Error!" + "\r" + e + ' ' + e.line);
  }
}

 

9 replies

Stephen Marsh
Community Expert
Community Expert
August 17, 2024

@Saharul islam - your post has no content. What's the purpose of your post?

Participant
April 19, 2024

@Stephen Marsh Muito obrigado! Eu resolvi as limitações do script criando uma ação para o photoshop.

Stephen Marsh
Community Expert
Stephen MarshCommunity ExpertCorrect answer
Community Expert
April 17, 2024

@magnos23200120 

 

As the script uses ExtendScript Action Manager code to retrieve the artboard bounds and to check if the layer is an artboard (as opposed to a group), this code may not work in older versions of Photoshop. I have tested in 2021 and 2024:

 

#target photoshop

  // Checks that the active layer is an artboard
  if (isArtboard() === true) {

    alert("Select a layer inside the artboard and run the script again...")

  } else {

    // Check that the current layer is a standard pixel layer
    if (app.activeDocument.activeLayer.typename === "ArtLayer" && app.activeDocument.activeLayer.kind === LayerKind.NORMAL) {

      // Set the ruler units to px, don't assume that they are set to px
      var originalRulerUnits = app.preferences.rulerUnits;
      app.preferences.rulerUnits = Units.PIXELS;

      // Set the original layer as a variable
      var theLayer = app.activeDocument.activeLayer;

      // Traverse the layers until the artboard is selected
      while (isArtboard() === false) {
        app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;
      }

      try {
        // Active Artboard Dimensions, by Rune L-H
        var ref = new ActionReference();
        ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
        var artBoardRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
        var artBoardRectWidth = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("right")) - artBoardRect.getDouble(stringIDToTypeID("left")), "px");
        var artBoardRectHeight = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("bottom")) - artBoardRect.getDouble(stringIDToTypeID("top")), "px");
      } catch (e) {
        alert("The problem could be that the layer is inside of a group..." + "\r" + e + ' ' + e.line);
        
        // Return to the original layer
        app.activeDocument.activeLayer = theLayer;
      }

      // Gets the layer dimensions
      var layerWidth = theLayer.bounds[2].value - theLayer.bounds[0].value;
      var layerHeight = theLayer.bounds[3].value - theLayer.bounds[1].value;

      // Calculates the total area of the screen/artboard
      var artboardArea = artBoardRectWidth.value * artBoardRectHeight.value;

      // Calculate the layer area
      var layerArea = layerWidth * layerHeight;

      // Calculate the total percentage of the layer
      var totalPercentage = (layerArea / artboardArea) * 100;

      // Checks if the layer occupies more than 30% of the screen/artboard
      if (totalPercentage >= 30) {
        alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the screen/artboard. Test passed!");
      } else {
        alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the canvas/artboard. Increase the layer to pass the test!");
      }

      // Return to the original layer
      app.activeDocument.activeLayer = theLayer;

    } else {
      alert("Ensure that a standard pixel layer is selected...");
    }

    // Return the original ruler units
    app.preferences.rulerUnits = originalRulerUnits;

  }


function isArtboard() {
  // modified from a script by greless with hints from jazz-y!
  // returns true or false
  try {
    var d = new ActionDescriptor();
    var r = new ActionReference();
    r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
    var options = executeActionGet(r);
    return options.hasKey(stringIDToTypeID('artboard')); // test for the required key
  } catch (e) {
    alert("Error!" + "\r" + e + ' ' + e.line);
  }
}

 

Stephen Marsh
Community Expert
Community Expert
April 17, 2024

@magnos23200120 

 

What version of Photoshop are you using?

 

The selected layer could be in nested groups and the parent of those groups has to be an artboard.

 

Your requirements are somewhat challenging. :]

Legend
April 17, 2024

The "catch" statement is there to deal with errors. Did you select a layer inside that artboard?

Participant
April 17, 2024
@Stephen Marsh It's working now! Thanks.
There are just two more problems, the script didn't run with that last line of "Catch".
And the other is: When the selected layer is within a group and/or subgroup, the script does not work.
The message is that photoshop understands that it does not have any information within the group


 

Stephen Marsh
Community Expert
Community Expert
April 16, 2024

@magnos23200120 

 

Try this script, as it uses ExtendScript Action Manager code to retrieve the artboard bounds, it may not work on all versions of Photoshop. I have tested in v2021 and v2024:

 

#target photoshop

try {

    // Checks that the active layer is a group/artboard/frame
    if (app.activeDocument.activeLayer.typename === "LayerSet") {

        alert("Select a layer inside the artboard and run the script again...")

    } else {

        // Set the ruler units to px, don't assume that they are set to px
        var originalRulerUnits = app.preferences.rulerUnits;
        app.preferences.rulerUnits = Units.PIXELS;

        // Set the original layer as a variable
        var theLayer = app.activeDocument.activeLayer;

        // Select the parent of the active layer, which is *assumed* to be an artboard
        app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;

        try {
            // Active Artboard Dimensions, by Rune L-H
            var ref = new ActionReference();
            ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
            var artBoardRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
            var artBoardRectWidth = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("right")) - artBoardRect.getDouble(stringIDToTypeID("left")), "px");
            var artBoardRectHeight = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("bottom")) - artBoardRect.getDouble(stringIDToTypeID("top")), "px");
        } catch (e) {
            alert("The problem could be that the layer is inside of a group..." + "\r" + e + ' ' + e.line);
            // Return to the original layer
            app.activeDocument.activeLayer = theLayer;
        }

        // Get the active layer
        var layer = app.activeDocument.activeLayer;

        // Gets the layer dimensions
        var layerWidth = theLayer.bounds[2].value - theLayer.bounds[0].value;
        var layerHeight = theLayer.bounds[3].value - theLayer.bounds[1].value;

        // Calculates the total area of the screen/artboard
        var artboardArea = artBoardRectWidth.value * artBoardRectHeight.value;

        // Calculate the layer area
        var layerArea = layerWidth * layerHeight;

        // Calculate the total percentage of the layer
        var totalPercentage = (layerArea / artboardArea) * 100;

        // Checks if the layer occupies more than 30% of the screen/artboard
        if (totalPercentage >= 30) {
            alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the screen/artboard. Test passed!");
        } else {
            alert("The layer occupies **" + totalPercentage.toFixed(2) + "%** of the canvas/artboard. Increase the layer to pass the test!");
        }

        // Return to the original layer
        app.activeDocument.activeLayer = theLayer;

        // Return the original ruler units
        app.preferences.rulerUnits = originalRulerUnits;
    }

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

 

P.S. I'll ask a moderator to change this topic from "bugs" to "discussion", bugs are for Adobe bugs, not for problems with code created by generative AI platforms.

Participant
April 16, 2024

Hi, Stephen! Thanks for the quick response.

I'm a layman and I made this script with the help of Google Gemini...

How exactly do I apply what you said to my code?

Stephen Marsh
Community Expert
Community Expert
April 16, 2024

Perhaps you can make use of the following ExtendScript + Action Manager code:

 

var originalRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;

var theLayer = app.activeDocument.activeLayer;

app.activeDocument.activeLayer = app.activeDocument.activeLayer.parent;

///// Active Artboard Dimensions, by Rune L-H /////
var ref = new ActionReference();
ref.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt"));
var artBoardRect = executeActionGet(ref).getObjectValue(stringIDToTypeID("artboard")).getObjectValue(stringIDToTypeID("artboardRect"));
var artBoardRectWidth = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("right")) - artBoardRect.getDouble(stringIDToTypeID("left")), "px");
var artBoardRectHeight = new UnitValue(artBoardRect.getDouble(stringIDToTypeID("bottom")) - artBoardRect.getDouble(stringIDToTypeID("top")), "px");
/////

alert(artBoardRectWidth.value + " x " + artBoardRectHeight.value + " px");

app.activeDocument.activeLayer = theLayer;

app.preferences.rulerUnits = originalRulerUnits;

 

You need to have a layer within an artboard selected before running the script.