Problem with layer bounds rectangle reported by script
Posted: Tue Feb 10, 2009 7:22 pm
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.
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.