Problem with layer bounds rectangle reported by script

Discussion of actual or possible Photoshop Scripting Bugs, Anomalies and Documentation Errors

Moderators: Tom, Kukurykus

squidbot

Problem with layer bounds rectangle reported by script

Post by squidbot »

OK, I've got another problem with the same script I asked about earlier, and you all seem to be more photoshop experts than me, so I'll try again. The problem is that the bounds rectangle for a layer sometimes seems to be wrong by a few pixels. My suspicion is that the bounds rect uses some sort of alpha threshold and it's ignoring a few pixels of anti-aliasing or the like. But this is only a guess, and even if it's correct, I don't know how I'd fix it. Of course, it could just be a bug in my script, because my Photoshop knowledge is actually pretty limited, I'm a programmer

My code is as follows. The idea is to go through each layer and put the layer in its own image, and save it out as its own PNG file, trimmed to size, and encoding the x and y values relative to the original canvas size.

The source of the error is the lines:

var x = doc.activeLayer.bounds[0]
var y = doc.activeLayer.bounds[1]

The x and y values are sometimes incorrect by a few pixels, not usually more than 2 or 3. 90% of the time they are correct. Most of the times they are wrong the layer has layer effects on it, but I've found cases where no layer effects exist but the problem is there, and flattening doesn't help either.

Thanks for any help you can provide!

Code: Select allvar doc = app.activeDocument;
var strtRulerUnits = app.preferences.rulerUnits;
var strtTypeUnits = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;

// save current state so we can close and reopen at end
doc.save()

var destFolder = new Folder(doc.path.toString() + "/export");
if(!destFolder.exists)
{
   destFolder.create();
}

var numLayers = doc.artLayers.length;

// mark all layers invisible to begin with
for(var layer = 0; layer < numLayers; ++layer)
{
   doc.artLayers[layer].visible = false
}

// go through each layer, make visible, copy all in to new document, then save
for(var layer = 0; layer < numLayers; ++layer)
{
   doc.activeLayer = doc.artLayers[layer];
   if(doc.activeLayer.kind == LayerKind.NORMAL)
   {
      doc.activeLayer.visible = true
      
      // set opacity to 100 for the exported image as it's set by a programmer in game since it
      // sometimes needs to have no opacity
      var originalOpacity = doc.activeLayer.opacity
      doc.activeLayer.opacity = 100
      
      var x = doc.activeLayer.bounds[0]
      var y = doc.activeLayer.bounds[1]

      var zOrder = numLayers - layer - 1;

      var temp = app.documents.add(doc.width, doc.height, doc.resolution, "temp", NewDocumentMode.RGB, DocumentFill.TRANSPARENT)
      
      app.activeDocument = doc
      var layerSet = doc.activeLayer
      layerSet.duplicate(temp)
      app.activeDocument = temp

      app.activeDocument.revealAll()
      app.activeDocument.trim(TrimType.TRANSPARENT)

      var trimmed = new File(
         destFolder.fsName + "/" +
         zeroPad(zOrder, 3) + "_" +
         parseInt(x) + "_" +
         parseInt(y) + "_"  +
         parseInt(originalOpacity) + "_" +
         doc.activeLayer.name + ".png");

      SavePNG(trimmed);
      app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

      doc.activeLayer.opacity = originalOpacity
      doc.activeLayer.visible = false
   }

}

app.preferences.rulerUnits = strtRulerUnits;
app.preferences.typeUnits = strtTypeUnits;

// open up fresh
var docFile = doc.fullName;
doc.close(SaveOptions.DONOTSAVECHANGES);
app.open(docFile);

function zeroPad(n, s)
{
   n = n.toString();
   while (n.length < s)
      n = '0' + n;
   return n;
}

function SavePNG(saveFile)
{
   var opt = new PNGSaveOptions();
   opt.interlaced = false;
   activeDocument.saveAs(saveFile, opt, true, Extension.LOWERCASE);
}



PS - Obviously I haven't added the code to go through the layers more quickly that was mentioned in the other post.
Mike Hale

Problem with layer bounds rectangle reported by script

Post by Mike Hale »

I think that there are several issues that can affect this. One is layer Fx. Another is transparency. And the last is that a layer's bounds can be larger than the document's

Here is a thread that covers some of those issues http://ps-scripts.com/bb/viewtopic.php? ... torder=asc? ... torder=asc
setien

Problem with layer bounds rectangle reported by script

Post by setien »

It can get much worse than a few pixels.
If you create a layer from an effect, the layer bounds will be the same as document bounds, even if the create layer contains only a single opaque pixel.
Mike Hale

Problem with layer bounds rectangle reported by script

Post by Mike Hale »

setien wrote:If you create a layer from an effect, the layer bounds will be the same as document bounds, even if the create layer contains only a single opaque pixel.
That is not always true. If you make a new 11x14in@300ppi doc then with the pencil tool and 1 pixel hard brush click once somewhere near the middle of the doc. Now add a drop shadow style with distance, spread, and size maxed out. If you get the layer bounds you will find that it is much larger than the doc bounds.

That is an extreme example. The bounds could be less than the doc with more normal settings.