Checking for an empty canvas

Hi everybody

Could someone tell me how I can check if the canvas is completely empty ?

The case include when one or more layers are present but none is visible , or only some layer is visible that is different from pixel (i.e only adjustment layer ) causing the canvas to show nothing

See examples below

Thanks
Daniele

Example 1

Example 2

You could try to select visible pixels of the composite channel and see what is the result.

Loop through layers and check if each layer is a) visible and b) is an adjustment layer (using constants - https://developer.adobe.com/photoshop/uxp/2022/ps_reference/modules/constants/#layerkind).
You’ll also need to do this recursively to handle any layer groups and their child layers.

Worth noting that various adjustment layers can render changes to a empty canvas, such as solid colour or gradient for example.
You’ll also probably want to check layer opacity and fill as no guarantee that they haven’t been set to 0% whilst the layer is visible this giving you a false positive. Likewise, layer masks also could present a problem.

To be honest, it strikes me as a super unreliable approach, @Jarda’s approach would be much more elegant and robust.

More elegant would be to read histogram but sadly it can’t handle alpha values :frowning:
You can read also histogram per channel and transparency is one of the hidden channels. But I am afraid it won’t work.

Tahnks @Jarda

I’m not sure I understood you reply, how to implement it and if it is the same solution that I was applying, that I’m going to describe here

What I was doing till now is to TRY to find a selection bound via batchplay (bounds.width) and if I CATCH an error it means that the canvas is empty, This works except the case when the selected layer is of a Pixel kind . Unfortunately if the selected layer is of a Pixel kind the TRY on the selection bounds doesn’t fail even if the level is not visible (see image below) and the canvas is empty, So the trick doesn’t work …

Thanks @Timothy_Bennett I agree with you that the approach could be therically correct but not very practical and reliable to apply

Not sure if that is what @Jarda meant by “composite channel”, but you could create a new layer and run the Stamp Visible command, which merges all visible pixels onto that layer. I don’t know where to find it in the menus, but the shortcut on Windows is Ctrl+Shift+Alt+E, and this is the batchPlay descriptor:

{
   "_obj": "mergeVisible",
   "duplicate": true,
}

If you then try to select the active pixels, you could catch the error due to the stamp layer being empty:

1 Like

I meant something like:

async function actionCommands() {
   const {batchPlay} = require("photoshop").action;

   const result = await batchPlay(
      [
         {
            _obj: "set",
            _target: [
               {
                  _ref: "channel",
                  _property: "selection"
               }
            ],
            to: {
               _ref: "channel",
               _enum: "channel",
               _value: "RGB"
            },
            _options: {
               dialogOptions: "dontDisplay"
            }
         }
      ],
      {
         modalBehavior: "execute"
      }
   );
}

async function runModalFunction() {
   await require("photoshop").core.executeAsModal(actionCommands, {"commandName": "Action Commands"});
}

await runModalFunction();

or

async function actionCommands() {
   const {batchPlay} = require("photoshop").action;

   const result = await batchPlay(
      [
         {
            _obj: "set",
            _target: [
               {
                  _ref: "channel",
                  _property: "selection"
               }
            ],
            to: {
               _ref: "channel",
               _enum: "channel",
               _value: "transparencyEnum"
            },
            _options: {
               dialogOptions: "dontDisplay"
            }
         }
      ],
      {
         modalBehavior: "execute"
      }
   );
}

async function runModalFunction() {
   await require("photoshop").core.executeAsModal(actionCommands, {"commandName": "Action Commands"});
}

await runModalFunction();

But it does not work as we need it. :-/ So stamp visible is better I think.
Also, keep in mind that some color modes can’t have layers at all therefore you can’t stamp it.

AFAIK stamp visible has never actually been present in the menu and was only available as a shortcut - mind you, I’ve been calling it “merge and float to new layer” for 20+ years and so that might be why I’ve never found it!

I searched for like 2 minutes before posting and eventually gave up, so I figured there might just not be a menu command :smiley: And you’re totally right calling it like that, I only learned by posting the batchPlay that it’s actually just the mergeVisible with more options.

yes stamp visible - or whatever we want to call it - seems to be the closest solution by now,.If fail the canvas is empty. But if it doesn’t fail create a new layer and I have to remove it. Not so good for performance