I've got 3 questions:
1. I've noticed that when the "Transparency Shapes Layer" checkbox in the Layer Style->Advanced Blending is turned off my layer bounds in the script become equal to the document bounds. Why does this happen?
See image attached for this checkbox:
2. Is it possible to check with the script if it's turned off and turn it on?
3. Are there any other options that may affect layer bounds?
Art layer - incorrect bounds
-
Mike Hale
Art layer - incorrect bounds
1. My guess is that options is a hold over from when Photoshop did not have adjustment layers. With that unchecked a blank layer with the color, pattern, or gradient overlay effect has the same appearance as color, pattern, or gradient fill adjustment layer. Some useful effects can also be done with a blank layer and a satin effect with that option unchecked. It seems to disable most of the other effects.
2. A good number of the options in the advance blending dialog can not be determined by a script. 'transparencyShapesLayer' is one of those options. You can set it with action manager code but it is not part of the layer's descriptor so can't be read. However you can still load the layer's transparency as a selection and get the bounds of the selection.
3. The drop shadow, outer glow effect change the layer bounds. So does stroke when set to stroke center or outside. Others may as well but those are the ones I am aware that do change the bounds.
2. A good number of the options in the advance blending dialog can not be determined by a script. 'transparencyShapesLayer' is one of those options. You can set it with action manager code but it is not part of the layer's descriptor so can't be read. However you can still load the layer's transparency as a selection and get the bounds of the selection.
3. The drop shadow, outer glow effect change the layer bounds. So does stroke when set to stroke center or outside. Others may as well but those are the ones I am aware that do change the bounds.
-
irov
Art layer - incorrect bounds
Thank you
Is it possible to somehow reset layer blending options to default settings then?
Is it possible to somehow reset layer blending options to default settings then?
-
Mike Hale
Art layer - incorrect bounds
I don't know of a way to reset all the blending options to default. But the code below with set 'transparencyShapesLayer' to true.
Code: Select allfunction ftn1() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc.putReference( charIDToTypeID('null'), ref );
var blendDesc = new ActionDescriptor();
blendDesc.putBoolean( stringIDToTypeID('transparencyShapesLayer'), true );
desc.putObject( charIDToTypeID('T '), charIDToTypeID('Lyr '), blendDesc );
executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );
};
Code: Select allfunction ftn1() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc.putReference( charIDToTypeID('null'), ref );
var blendDesc = new ActionDescriptor();
blendDesc.putBoolean( stringIDToTypeID('transparencyShapesLayer'), true );
desc.putObject( charIDToTypeID('T '), charIDToTypeID('Lyr '), blendDesc );
executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );
};
-
kpt
Art layer - incorrect bounds
Just found this thread and needed a bit of code to figure out the layer bounds, disregarding the effects. I've used some code from other prominent members on this board
Code: Select all
groupSelectedLayers = function() {
var desc = new ActionDescriptor();
var r1 = new ActionReference();
r1.putClass(ST("layerSection"));
desc.putReference( CT("null"), r1);
var r2 = new ActionReference();
r2.putEnumerated(CT("Lyr "),
CT("Ordn"),
CT("Trgt"));
desc.putReference(CT("From"), r2);
executeAction(CT("Mk "), desc, DialogModes.NO);
};
getSelectedLayers = function() {
try {
groupSelectedLayers();
var groupLayers = activeDocument.activeLayer.layers;
var selectedLayers = new Array;
for (var i = 0; i < groupLayers.length; i++) {
selectedLayers.push(groupLayers);
}
executeAction(CT("undo"), undefined, DialogModes.NO);
return selectedLayers;
} catch (e) {
return false;
}
};
getLayerIndex = function(layer) {
var doc = app.activeDocument;
var al = doc.activeLayer;
var vis = al.visible;
var res = undefined;
if (layer != doc.activeLayer)
doc.activeLayer = layer;
try {
var ref = new ActionReference();
ref.putEnumerated(CT("Lyr "), CT("Ordn"), CT("Trgt"));
res = executeActionGet(ref);
} finally {
if (doc.activeLayer != al)
doc.activeLayer = al;
doc.activeLayer.visible = vis;
}
var i = res.getInteger(CT("ItmI"));
return i + (doc.layers[doc.layers.length-1].isBackgroundLayer ? -1 : 0);
};
selectLayerByIndex = function(index, augment) {
if (augment) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIndex(CT("Lyr "), index);
desc.putReference( CT("null"), ref);
desc.putEnumerated(ST("selectionModifier"),
ST("selectionModifierType"),
ST("addToSelection"));
desc.putBoolean( CT("MkVs"), false);
executeAction( CT("slct"), desc, DialogModes.NO);
} else {
var ref = new ActionReference();
ref.putIndex(CT("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(CT("null"), ref);
executeAction(CT("slct"), desc, DialogModes.NO);
}
};
selectLayersByIndex = function(idxs) {
if (!idxs || idxs.length == 0)
return;
selectLayerByIndex(idxs.pop(), false);
while (idxs.length) {
selectLayerByIndex(idxs.pop(), true);
}
};
selectLayers = function(layers) {
var idxs = [];
var vis = [];
for (var i = 0; i < layers.length; i++) {
var l = layers;
vis = l.visible;
idxs.push(getLayerIndex(l));
}
selectLayersByIndex(idxs);
for (var i = 0; i < layers.length; i++) {
var l = layers;
l.visible = vis;
}
};
hasLayerEffects = function() {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
return executeActionGet(ref).getBoolean(stringIDToTypeID('layerFXVisible'));
};
disableLayerEffects = function() {
try {
var idHd = charIDToTypeID( "Hd " );
var desc157 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list16 = new ActionList();
var ref102 = new ActionReference();
var idLefx = charIDToTypeID( "Lefx" );
ref102.putClass( idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref102.putEnumerated( idLyr, idOrdn, idTrgt );
list16.putReference( ref102 );
desc157.putList( idnull, list16 );
executeAction( idHd, desc157, DialogModes.NO );
return true;
} catch (e) {
return false;
};
};
enableLayerEffects = function() {
try {
var idShw = charIDToTypeID( "Shw " );
var desc167 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list22 = new ActionList();
var ref112 = new ActionReference();
var idLefx = charIDToTypeID( "Lefx" );
ref112.putClass( idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref112.putEnumerated( idLyr, idOrdn, idTrgt );
list22.putReference( ref112 );
desc167.putList( idnull, list22 );
executeAction( idShw, desc167, DialogModes.NO );
return true;
} catch (e) {
return false;
}
};
layerBounds = function(l) {
var selectedLayers = getSelectedLayers();
app.activeDocument.activeLayer = l;
var fx = hasLayerEffects();
if (fx)
disableLayerEffects();
var b = l.bounds;
if (fx)
enableLayerEffects();
selectLayers(selectedLayers);
return b;
};
bounds2str = function(b) {
return "(" + b[0].as("px") + "," + b[1].as("px") + ")-(" + b[2].as("px") + "," + b[3].as("px") + ")";
};
var doc = app.activeDocument;
var l1 = doc.artLayers.getByName("My layer");
alert(l1 + ": " + bounds2str(layerBounds(l1)));
Code: Select all
groupSelectedLayers = function() {
var desc = new ActionDescriptor();
var r1 = new ActionReference();
r1.putClass(ST("layerSection"));
desc.putReference( CT("null"), r1);
var r2 = new ActionReference();
r2.putEnumerated(CT("Lyr "),
CT("Ordn"),
CT("Trgt"));
desc.putReference(CT("From"), r2);
executeAction(CT("Mk "), desc, DialogModes.NO);
};
getSelectedLayers = function() {
try {
groupSelectedLayers();
var groupLayers = activeDocument.activeLayer.layers;
var selectedLayers = new Array;
for (var i = 0; i < groupLayers.length; i++) {
selectedLayers.push(groupLayers);
}
executeAction(CT("undo"), undefined, DialogModes.NO);
return selectedLayers;
} catch (e) {
return false;
}
};
getLayerIndex = function(layer) {
var doc = app.activeDocument;
var al = doc.activeLayer;
var vis = al.visible;
var res = undefined;
if (layer != doc.activeLayer)
doc.activeLayer = layer;
try {
var ref = new ActionReference();
ref.putEnumerated(CT("Lyr "), CT("Ordn"), CT("Trgt"));
res = executeActionGet(ref);
} finally {
if (doc.activeLayer != al)
doc.activeLayer = al;
doc.activeLayer.visible = vis;
}
var i = res.getInteger(CT("ItmI"));
return i + (doc.layers[doc.layers.length-1].isBackgroundLayer ? -1 : 0);
};
selectLayerByIndex = function(index, augment) {
if (augment) {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putIndex(CT("Lyr "), index);
desc.putReference( CT("null"), ref);
desc.putEnumerated(ST("selectionModifier"),
ST("selectionModifierType"),
ST("addToSelection"));
desc.putBoolean( CT("MkVs"), false);
executeAction( CT("slct"), desc, DialogModes.NO);
} else {
var ref = new ActionReference();
ref.putIndex(CT("Lyr "), index);
var desc = new ActionDescriptor();
desc.putReference(CT("null"), ref);
executeAction(CT("slct"), desc, DialogModes.NO);
}
};
selectLayersByIndex = function(idxs) {
if (!idxs || idxs.length == 0)
return;
selectLayerByIndex(idxs.pop(), false);
while (idxs.length) {
selectLayerByIndex(idxs.pop(), true);
}
};
selectLayers = function(layers) {
var idxs = [];
var vis = [];
for (var i = 0; i < layers.length; i++) {
var l = layers;
vis = l.visible;
idxs.push(getLayerIndex(l));
}
selectLayersByIndex(idxs);
for (var i = 0; i < layers.length; i++) {
var l = layers;
l.visible = vis;
}
};
hasLayerEffects = function() {
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
return executeActionGet(ref).getBoolean(stringIDToTypeID('layerFXVisible'));
};
disableLayerEffects = function() {
try {
var idHd = charIDToTypeID( "Hd " );
var desc157 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list16 = new ActionList();
var ref102 = new ActionReference();
var idLefx = charIDToTypeID( "Lefx" );
ref102.putClass( idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref102.putEnumerated( idLyr, idOrdn, idTrgt );
list16.putReference( ref102 );
desc157.putList( idnull, list16 );
executeAction( idHd, desc157, DialogModes.NO );
return true;
} catch (e) {
return false;
};
};
enableLayerEffects = function() {
try {
var idShw = charIDToTypeID( "Shw " );
var desc167 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var list22 = new ActionList();
var ref112 = new ActionReference();
var idLefx = charIDToTypeID( "Lefx" );
ref112.putClass( idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref112.putEnumerated( idLyr, idOrdn, idTrgt );
list22.putReference( ref112 );
desc167.putList( idnull, list22 );
executeAction( idShw, desc167, DialogModes.NO );
return true;
} catch (e) {
return false;
}
};
layerBounds = function(l) {
var selectedLayers = getSelectedLayers();
app.activeDocument.activeLayer = l;
var fx = hasLayerEffects();
if (fx)
disableLayerEffects();
var b = l.bounds;
if (fx)
enableLayerEffects();
selectLayers(selectedLayers);
return b;
};
bounds2str = function(b) {
return "(" + b[0].as("px") + "," + b[1].as("px") + ")-(" + b[2].as("px") + "," + b[3].as("px") + ")";
};
var doc = app.activeDocument;
var l1 = doc.artLayers.getByName("My layer");
alert(l1 + ": " + bounds2str(layerBounds(l1)));
-
Mike Hale
Art layer - incorrect bounds
If you are talking about getting the bounds without layer effects such as drop shadow,etc Adobe has added a new key to the layer descriptor with the stringID "boundsNoEffects". It gives the same bounds as turning off the effects then getting the bounds. But 'transparencyShapesLayer' is still a problem.
-
kpt
Art layer - incorrect bounds
Interesting! Do you mind telling me how to use this in actual code? I've only been using layer.bounds so far.
-
Mike Hale
Art layer - incorrect bounds
Code: Select allvar trueBoundsDesc = getProperty(charIDToTypeID('Lyr '),stringIDToTypeID('boundsNoEffects'));
var width = trueBoundsDesc.getUnitDoubleValue(charIDToTypeID('Wdth'));
alert(width);
/*
the keys in the descriptor are all UnitDouble data type
Key 01 = "Top " | "top"
Key 02 = "Left" | "left"
Key 03 = "Btom" | "bottom"
Key 04 = "Rght" | "right"
Key 05 = "Wdth" | "width"
Key 06 = "Hght" | "height"
*/
function getProperty( psClass, psKey, index ){// integer:Class, integer:key
var ref = new ActionReference();
if( psKey != undefined ) ref.putProperty( charIDToTypeID( "Prpr" ), psKey );
if(index != undefined ){
ref.putIndex( psClass, index );
}else{
ref.putEnumerated( psClass , charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
}
try{
var desc = executeActionGet(ref);
}catch(e){ return; }// return on error
if(desc.count == 0) return;// return undefined if property doesn't exists
var dataType = desc.getType(psKey);
switch(dataType){// not all types supported - returns undefined if not supported
case DescValueType.INTEGERTYPE:
return desc.getInteger(psKey);
break;
case DescValueType.ALIASTYPE:
return desc.getPath(psKey);
break;
case DescValueType.BOOLEANTYPE:
return desc.getBoolean(psKey);
break;
case DescValueType.BOOLEANTYPE:
return desc.getBoolean(psKey);
break;
case DescValueType.UNITDOUBLE:
return desc.getUnitDoubleValue(psKey);
break;
case DescValueType.STRINGTYPE:
return desc.getString(psKey);
break;
case DescValueType.OBJECTTYPE:
return desc.getObjectValue(psKey);
break;
case DescValueType.LISTTYPE:
return desc.getList(psKey);
break;
case DescValueType.ENUMERATEDTYPE:
return desc.getEnumerationValue(psKey);
break;
}
};
var width = trueBoundsDesc.getUnitDoubleValue(charIDToTypeID('Wdth'));
alert(width);
/*
the keys in the descriptor are all UnitDouble data type
Key 01 = "Top " | "top"
Key 02 = "Left" | "left"
Key 03 = "Btom" | "bottom"
Key 04 = "Rght" | "right"
Key 05 = "Wdth" | "width"
Key 06 = "Hght" | "height"
*/
function getProperty( psClass, psKey, index ){// integer:Class, integer:key
var ref = new ActionReference();
if( psKey != undefined ) ref.putProperty( charIDToTypeID( "Prpr" ), psKey );
if(index != undefined ){
ref.putIndex( psClass, index );
}else{
ref.putEnumerated( psClass , charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
}
try{
var desc = executeActionGet(ref);
}catch(e){ return; }// return on error
if(desc.count == 0) return;// return undefined if property doesn't exists
var dataType = desc.getType(psKey);
switch(dataType){// not all types supported - returns undefined if not supported
case DescValueType.INTEGERTYPE:
return desc.getInteger(psKey);
break;
case DescValueType.ALIASTYPE:
return desc.getPath(psKey);
break;
case DescValueType.BOOLEANTYPE:
return desc.getBoolean(psKey);
break;
case DescValueType.BOOLEANTYPE:
return desc.getBoolean(psKey);
break;
case DescValueType.UNITDOUBLE:
return desc.getUnitDoubleValue(psKey);
break;
case DescValueType.STRINGTYPE:
return desc.getString(psKey);
break;
case DescValueType.OBJECTTYPE:
return desc.getObjectValue(psKey);
break;
case DescValueType.LISTTYPE:
return desc.getList(psKey);
break;
case DescValueType.ENUMERATEDTYPE:
return desc.getEnumerationValue(psKey);
break;
}
};
-
kpt
Art layer - incorrect bounds
Another bit of magic, thanks Mike! Do you know with which version the boundsNoEffects was introduced in Photoshop?