CreativePro Forum
Join our community of graphic designers, publishers, and production artists from around the world. Our members-only forum is a great place to discuss challenges and find solutions!
- You must be logged in to reply to this topic.Login
Automate change object layer option
- This topic has 15 replies, 3 voices, and was last updated 3 years, 3 months ago by
Theo de Klerk.
-
AuthorPosts
-
-
May 21, 2022 at 11:08 am #14365995
Theo de Klerk
ParticipantI’ve got a number of Photoshop files with each 2 groups of layers, say A and B, changing the appearance of the image accordingly by different adjustments of levels and curves.
In InDesign these files take up a whole page. The document has also two layers, A and B. Depending on requirements I enable layer A or B for exporting a pdf file.
I was pleased to know that InDesign can link its layer-dependent output to layers in the image files.
However, as soon as you modify the existing Photoshop layer (different values in an adjustment level) suddenly InDesign updates its document to use that latest PhotoShop layer. What was set to use Photoshop layer B suddenly uses A.
This totally defeats the purpose of layers in a document when it loses the link with the image.Is there any way to automate (e.g. when you modified the layer B in Photoshop):
1. set layer of InDesign document (say layer A)
2. Set object layer option of image on that layer to use Photoshop layer A alsoI’ve looked everywhere but, not knowing JavaScript but familiar with Visual Basic, I see no way to:
For each page do
set layer A
for each image do
set object layer option = layer A
next
nextSeems like a no-brainer to me, but manually you can only do it image by image (and there are thousands…) and I cannot find anything in the object model that uses the object layer option (as property).
Has someone written such a routine or can point me in the right direction?
-
May 21, 2022 at 12:32 pm #14366003
David BlatnerKeymasterAt the bottom of the Object Layer Options dialog box in InDesign, there is an option for “When Updating Link”… that should let you control what happens when the file updates: either keep the photoshop layers or keep the layer overrides.
More info here (the article is about illustrator, but it’s the same mechanism)
and this preference may also help:
A Fix for Problems With Layer Visibility Overrides In Placed Illustrator Files
and this script won’t help you directly, but it’s cool:
A Script to Change Layer Visibility of All Instances of a Placed File in InDesign
-
May 21, 2022 at 1:21 pm #14366004
Theo de Klerk
ParticipantUnfortunately that is completely ignored. Perhaps not for Illustrator, but for Photoshop it has zero impact.
I had set it to “Keep layer visibility override” as opposed to “Use Photoshop Layer Visibility”In Photoshop I don’t really care what layer(group) is visible. Usually either A or B, depending on what I changed last.
For InDesign it should not make a difference. That should keep showing either group A or B as specified in “on place”. But no, it changes into whatever layer was changed last.I have seen the script for changing layer visibility for A image. But on 300 pages I have 300 images, not one and the same over several pages. So the script (as far as I understood it) doesn’t help here. It’s not
for each page if image = name then set layer visibility
but
for each page for each image set layer visibility
-
May 21, 2022 at 7:11 pm #14366006
David BlatnerKeymasterThat is very strange. I just tested it and it works correctly for me.
I tried two different methods: setting the layers using the “show import options” dialog box (during Place) and using Object > Object Layer Options. I set layer visibility for the layered PSD file. Then I changed the PSD file and saved it. When I go back to InDesign and click Update, the layer visibility overrides that I set remain.The only thing I can think of is: Are you adding or deleting layers in the Photoshop file? That can confuse InDesign.
-
-
May 22, 2022 at 4:57 am #14366008
Theo de Klerk
ParticipantPloughing on some more psd files seem to retain their layer setting in InDesign. Some don’t. Some weeks ago I did indeed add layers and that confused InDesign completely (some message like “psd modified – now using psd settings”) and screwed up my setting. I believed, incorrectly, that when you set a layer in InDesign it should not matter what changes in the psd, it should keep selecting the specified layer (problem only if that one no longer exists).
I’ve since used a macro in photoshop to create both layer groups with some handy settings that I modify for each image. So adjustment settings change, layers remain and are not added/removed afterwards. That indeed seems to keep the layer setting in object layer options. So let’s hope it remains this way.Still… I am interested to know/be able to write a script that does what I want (set object layer option explicitly for each image on each page). I would think this a no-brainer but cannot find anything on object layers in the object model as far as I looked.
-
May 22, 2022 at 10:34 am #14366010
Theo de Klerk
ParticipantI changed psd files by adjusting the B layer (already present, just needed tweaking).
Then opening the InDesign file (with layer A filled with images psd using layer A) started with “xx links modified” message. OK. It replaced in layer A all objects to object layers B rather than not updating anything as nothing had changed in the psd A layers.Next I keep the InDesign file open with layer A containing psd files with object layer A. I modify a number of psd images in their layer B.
Then I open the layer B of InDesign’s file. Placing the psd files using their object layer B works fine. It does not interfere with what’s already on layer A.Closing the InDesign file and immediately afterwards re-opening it, it again mentions links are modified. Odd… nothing changed since the close. Confirming update also doesn’t seem to do anything.
A script doing exactly what I want would relieve me from this apparently unstable implementation.
-
May 22, 2022 at 10:36 am #14366011
David BlatnerKeymasterBe sure to check the setting of your Preferences (see the preference for adding/changing layers references in the article about Illustrator above).
I am not a scripter myself, but you might find some help on the “InDesign Scripting” group on Facebook.
-
May 22, 2022 at 12:33 pm #14366013
Theo de Klerk
ParticipantI may be looking at the wrong place but Edit>Preferences doesn’t mention layers at all. And I’ve read that “Keep layer option” finally seems to work for Illustrator but not Photoshop.
And indeed… layer A and B both had the same psd image with photoshop layer A and B enabled respectively. Close file, open file… links update… all become psd layer B. This really sucks!
I’ll have a look at the FB group – though nowhere do I find an object layer reference in InDesign’s object model so I don’t have my hopes up. -
May 24, 2022 at 7:54 am #14366031
Theo de Klerk
ParticipantI’ve looked at some examples and large modified the layered-visability example but it still won’t work completely – at some point the object that contains the psd layers vanishes – no idea why. Anyway, what I came up with sofar is written below. Any comment/correction welcomed!
Main();
//
// For all Photoshop PSD image placed in InDesign layers, set visibility of
// the PSD layers on only if the image resides on an InDesign layer with the same name,
// Any other layers in PSD with different names than InDesign layers are not affected
//
function Main()
{
// define all variables upfront so their scope is the entire main function
var page, placedFile, links, PSDlayer, i, j, k, doc;
var doc = app.activeDocument;
var pages = doc.pages
var PSDlayers;
var numChanges = 0;
var imageChange;
var docLayers = doc.layers;
var docLayerNames=[];// get names of InDesign layers
for (i=0; i< docLayers.length;i++)
{
docLayerNames.push(docLayers[i].name);
$.writeln (“1 ” +docLayers[i].name);
}// find all images by their links (working backwards) stored in InDesign and process them one by one
links = doc.links;
for (i = links.length-1; i>=0; i–)
{
// get the file info from the link: stored as “parent” of the link
placedFile = links[i].parent;// file must be an image, not null and made by Photoshop
if (placedFile.constructor.name == “Image” && placedFile.itemLink != null && placedFile.itemLink.linkType == “Photoshop”)
{
// traverse all InDesign layer names to see if PSD file has same layer name
for (k=0; k < docLayerNames.length; k++)
{
// find Photoshop layer by that name in the image. If it does not exist, the layer will be invalid
PSDlayer = placedFile.graphicLayerOptions.graphicLayers.item(docLayerNames[k]);if (PSDlayer.isValid)
{
$.writeln(“2 PSD layer ” + PSDlayer.name + ” visibility off”);
PSDlayer.currentVisibility = false;
}
}// selectively reset visibility of PSD layers with same name as ID layers
// traverse all InDesign layers
for (j=0;j<docLayerNames.length;j++)
{
imageChange = false;
$.writeln(“3 ID layer psd file = “, placedFile.itemLayer.name);
if (placedFile.itemLayer.name == docLayerNames[j])
{
PSDlayer = placedFile.graphicLayerOptions.graphicLayers.item(docLayerNames[j]);
$.writeln (“4 PSD layer = “+PSDLayer.name);
if (PSDlayer.isValid)
{
PSDlayer.currentVisibility = true;
imageChange = true;
$.writeln(“5 layer ” + PSDlayer.name + ” visibility on”);
}
}
}
// count the number of changes made
if (imageChange)
numChanges++;
}
}
alert(“Done, made changes in “+numChanges+” images”);
}-
May 24, 2022 at 12:39 pm #14366036
Theo de Klerk
ParticipantI’ve cut it down to a script that has part 1 that just displays the info I need (writes it to the console – you you may need to open the script for editing to see the console). Part 2 attempts to reset visibility of all PSD layers to off.
Part 1 runs without problem and does show the info I need.
Part 2 is mostly a copy of Part 1 but suddenly finds a PSD layers object that doesn’t exist anymore (why?) and occassionally brings InDesign in a loop that can only be aborted by stopping the application via Task Manager. Very odd.
Part 3 (to add) will repeat part 2 but when InDesign layer name = PSD layer name, set visibility true. In the end only part 2 and 3 are required for the script obviously.
But somewhere it goes wrong in Part 2 and I don’t know why.Main();
//
// show ID layers and PSD layers
//
function Main()
{
// ========= PART 0 – VARIABLES DEFINITIONS =============================// define all variables upfront so their scope is the entire main function
var placedFile, links, PSDlayers, PSDlayer, i, j, k, doc;
var docLayers;
var IDlayer;doc = app.activeDocument;
docLayers = doc.layers;// ========= P ART 1 – GET THE LAYER (NAME) INFORMATION =================
// get names of InDesign layers
$.writeln(“InDesign layers”);
for (i=0; i< docLayers.length;i++)
{
//docLayerNames.push(docLayers[i].name);
$.writeln (” “+ docLayers[i].name);
}
$.writeln(“—-“);
$.writeln(“PSD layers”);// find all images by their links (working backwards) stored in InDesign and process them one by one
links = doc.links;
for (i = links.length-1; i>=0; i–)
{
// get the file info from the link: stored as “parent” of the link
placedFile = links[i].parent;
IDlayer = placedFile.itemLayer;// file must be an image, not null and made by Photoshop
if (placedFile.constructor.name == “Image” && placedFile.itemLink != null && placedFile.itemLink.linkType == “Photoshop”)
{
// layers of PSD
$.writeln (“File on ID layer: ‘” + IDlayer.name + “‘ has the following layers:” );
PSDlayers = placedFile.graphicLayerOptions.graphicLayers;
for (k=0;k< PSDlayers.length;k++)
{
PSDlayer = PSDlayers.item(k);
$.writeln(” ” + PSDlayer.name );
}
$.writeln(“==== “);
}
}// ============= PART 2 RESET VISIBILITY OF ALL LAYERS WITH SAME NAMES FOR PSD AND InDesign ======================
// Reset visibility of all PSD layers with same name ID layers
links = doc.links;
for (i = links.length-1; i>=0; i–)
{
// get the file info from the link: stored as “parent” of the link
placedFile = links[i].parent;
// IDlayer = placedFile.itemLayer;// file must be an image, not null and made by Photoshop
if (placedFile.constructor.name == “Image” && placedFile.itemLink != null && placedFile.itemLink.linkType == “Photoshop”)
{
// layers of PSD
PSDlayers = placedFile.graphicLayerOptions.graphicLayers;// per PSD layer check if a match is made with ID layer
for (k=0;k< PSDlayers.length;k++)
{
PSDlayer = PSDlayers.item(k);
for (i = 0;i<docLayers.length;i++)
{ $.writeln(“ID layer = ” + docLayers[i].name);
if (docLayers[i].name == PSDlayer.name)
{$.writeln (” Found same name PSD layer (reset): “+ PSDlayer.name);
PSDlayer.currentVisibility=false;
}
}
}
}
}// ============= END OF FUNCTION MAIN ==============================
}
-
-
May 24, 2022 at 12:42 pm #14366037
Theo de Klerk
Participantoh, some items have i– that should read (when not beautfied by this site) i – – (two minusses )
-
June 11, 2022 at 6:42 am #14366657
Theo de Klerk
ParticipantI solved my problem – partly but enough for me. A little adjustment to the LayerVisibility script worked for me.
Just go to InDesign and set a particular layer current. Then run the script that you filled with the two PhotoShop layers that should be present in all images (ignoring any other that might be there) and run it. That script works fine with a little more handwork than I hoped for, but it beats manually modifying each InDesign Object Layer Option.Main();
//
// set layers on/off in an image or images on one InDesign page
//
function Main()
{
var page, placedFile, links, layer, i, j, k, doc;
var doc = app.activeDocument;
var curLayer = doc.activeLayer;
var pages = doc.pagesvar checklist = [];
var PSlayernames = [ “extreme”, “subtle” ];
/* ——————————————————————————————————-
ABOVE IS WHERE YOU ALTER THE LAYER NAMES:
After the words “var layernames” there’s an opening square bracket , then some sets of text enclosed in quotes sperated by commas, and at the end, a closing square bracket.
Delete all of the text and the commas separating it, and in its place put in any layers that you want.
For example: If you have three layers, ‘red’, ‘green’ and ‘silver’, then in the brackets put in each layer enclosed in quotes and seperated by a comma, as such: [“red”, “green”, “silver”].
Make sure they are all double-quotes, not single quotes, and make sure they are ‘straight’ quotes not ‘smart’ quotes.
To ensure that it’s properly formatted, only edit the script in a generic text editor (such as Notepad on Windows, or Text Wrangler on Mac).
DO NOT use a word-proccesing program such as MS Word or InDesign, as that will add formatting to the script and it will not work properly.
——————————————————————————————————- */var ilDialog = app.dialogs.add({name:”Image Layers on/off on ” + curLayer.name, canCancel:true});
with (ilDialog)
{
with(dialogColumns.add())
{
with(dialogRows.add())
{
staticTexts.add ({staticLabel:”Check image layers to show, uncheck to hide on “+ curLayer.name});
for (i=0; i < PSlayernames.length; i++)
{
with(dialogRows.add())
checklist.push (checkboxControls.add({staticLabel:PSlayernames[i], checkedState:false}));
}
}
}
}
var numChanges = 0;
var imageChange;
if (ilDialog.show() == true)
{
// find all images by their links and process them one by one
links = doc.links;
for (i = links.length-1; i>=0; i- -)
{
// get the file info from the link: stored as “parent” of the link
placedFile = links[i].parent;// file must be an image, not null and made by Photoshop
if (placedFile.constructor.name == “Image” && placedFile.itemLink != null && placedFile.itemLink.linkType == “Photoshop” )
{
imageChange = false;
if (placedFile.itemLayer == curLayer)
{
// check layers names defined for change and see if this name corresponds witrh the Photoshop file layer
for (k=0; k < PSlayernames.length; k++)
{
// find Photoshop layer byt that name in the image. If it does not exist, the layer will be invalid
layer = links[i].parent.graphicLayerOptions.graphicLayers.item(PSlayernames[k]);// if layer exists, and if its visibility is not according to checklist in dialogbox, change it to match set visibility (if correct, don’t bother)
if (layer.isValid && layer.currentVisibility != checklist[k].checkedState)
{
layer.currentVisibility = checklist[k].checkedState;
imageChange = true;
}
}
// count the number of changes made
if (imageChange)
numChanges++;
}
}
}
alert(“Done, made changes in “+numChanges+” images”);
} else
{
ilDialog.destroy();
}
}-
June 16, 2022 at 7:21 am #14366748
David BlatnerKeymasterThank you for sharing, Theo! One tip: here on the forum, you should put programming code in HTML “pre” or “code” tags.
That way it appears like this:this is some code "and quotes and -- dashes are not changed"
:-)
-
-
June 15, 2022 at 3:35 am #14366695
Max Parker
Participantinteresting information
-
August 26, 2022 at 9:57 am #14371090
Theo de Klerk
ParticipantI’ve meanwhile become a bit more dangerous in JavaScript so I changed the original script into something more logical to me. Problem remains the same: for each document layer A, any Photoshop file in that layer should have its layer with the same name A visible, all other layers with a corresponding document layer, invisible. This leaves any other layer in the Photoshop file untouched (usually the “Background” layer with the main image. Layers or layergroups A then perform some adjustments on that background.
The code below provides a dialog box listing all layers in your document. Either pick one for all Photoshop files in that layer to be modified, or “All” to repeat the same process for each layer.
The script has a lot of $.writeln instructions commented out. They would output to the Javascript Console
/ SyncIDandPSDLayers.jsx
//
// Select an InDesign layer. Check for any Photoshop images on that layer in the document.
// If so, if the PSD file has a layer with the same name, set it visible
// set all other PSD layers that match with other InDesign layer names invisible
// Any non-matching layer name in PSD remains untouched (which usually includes the Background layer)
//
// Hence on ID layers X,Y,Z the Photoshop files have layer X visible and Y,Z invisible on the ID X layer if X layer is selected
// ,, Y X,Z Y Y
// ,, Z X,Y Z Z
//
// A n additional radiobutton allows all InDesign layers to be checkedmain();
exit();//--------------------------------------------------------------------------------------------------------------------------
function main()
{
var myDoc = app.activeDocument;
var myLayers = myDoc.layers;
var selectedLayer; // list of layers to process. Can be one or all
var numChanges;// ask what layer to use to modify images
selectedLayer = selectLayer(myLayers);numChanges = 0;
for (var i=0;i<selectedLayer.length;i++){
numChanges = + setPSDlayerVisible(selectedLayer[i])
};
alert ("Finished. \r Changed " + numChanges + " image layer visibility settings on " + selectedLayer.length + " InDesign layers");
exit();
}//--------------------------------------------------------------------------------------------------------------------------
function setPSDlayerVisible(selectedLayer){
// go through all pages of the document, select the layer indicated, open all images if PhotoShop made
// and set all layers invisbile except for layer with same name as selected layer
// Return the number of changed visibility properties in the Photoshop files in the specified document layervar links, placedFile, PSDlayer, numChanges;
// store all layers in InDesign document
var docLayers = app.activeDocument.layers;// start with no modifications
numChanges = 0;// only look for images that have their roots in external files, i.e. have links
links = app.activeDocument.links;
for (var i = 0; i < links.length; i++){// get the file info from the link: stored as "parent" of the link
placedFile = links[i].parent;// file must be an image, not null (not embedded) and made by Photoshop
if (placedFile.constructor.name == "Image" && placedFile.itemLink != null && placedFile.itemLink.linkType == "Photoshop" ){
//$.writeln ("1 found: "+ placedFile.itemLink.filePath + " on ID layer " + placedFile.itemLayer.name);imageChange = false;
//$.write ("2 PSD file on selected layer " );
if (placedFile.itemLayer == selectedLayer){
//$.writeln (" - Yes");// check if Photoshop file has a layer by the same name as one of the InDesign layers.
// If it does not exist, the layer will be invalid, if it does, check if the psd layer name matches an InDesign layer name.
// If that is so, set visibility true only for the layer with the same name as the selectedLayer, otherwise set layer invisible
for (var n = 0; n < docLayers.length;n++){
placedFile = links[i].parent; // after any modification of a linked object, it is replaced, so reset it to use the old object at its new location
layer = placedFile.graphicLayerOptions.graphicLayers.item(docLayers[n].name);if (layer.isValid){
if (layer.name == selectedLayer.name){
if (layer.currentVisibility != true){
//$.writeln("psd/InDesign layer names the same - layer set visible");
layer.currentVisibility = true;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names the same - layer already visible");
}
}
else{
if (layer.currentVisibility != false){
//$.writeln("psd/InDesign layer names different - layer set invisible");
layer.currentVisibility = false;
imageChange = true;
}
else{
//$.writeln("psd/InDesign layer names different - layer already invisible");
}
}// count the number of changes made
if (imageChange){
numChanges++;
}
else{
}
}
else{
//$.writeln ("Layer invalid (not found)");
}
} // next docLayer
}
else{
//$.writeln (" - No");
}
}
else{
//$.writeln ("No photoshop file");
}
} // next linked filereturn numChanges;
}function selectLayer(allLayers, nrLayers){
// present all layer names in document. Allow selection of a single one or all.
// The selection is returned as an array with only 1 element or as many as there are levels.
// Each element is added to the array by push and filled with a layer objectvar result=[];
// create dialog
var myDialog = app.dialogs.add({name:"Select document layer (with PSD images) ", canCancel:true});// within the dialog box it all happens in its columns - create a radiobutton group for a series of radiobuttons
// - one button for each layer plus a button for "all layers".
// Only one button can be selected at any time. The buttongroup will obtain its value.
// Set the first button as the initially selected layer.with (myDialog.dialogColumns.add () ){
with (borderPanels.add() ){
staticTexts.add({staticLabel:"Specify InDesign layer to sync Photoshop image layers:"});
var myRadioButtonGroup = radiobuttonGroups.add();
with(myRadioButtonGroup){
for (var i=0; i< allLayers.length; i++){
radiobuttonControls.add({staticLabel: allLayers[i].name});
}
radiobuttonControls.add({staticLabel: "All InDesign layers"});
radiobuttonControls[0].properties=({checkedState:true});
}
}
};// show the box
var myResult = myDialog.show();// check for OK or Cancel
if (myResult == true){
// make a difference between a single selected layer or all layers (selected button (last) then length-1 since buttons start to count from 0)
with (myDialog.dialogColumns[0].borderPanels[0].radiobuttonGroups[0]){
if(radiobuttonControls.length-1== myRadioButtonGroup.selectedButton ){
for (var i=0;i<allLayers.length;i++){
result.push(allLayers[i]);
}
}
else{ // array has a single element :the one selected layer
result.push (allLayers[myRadioButtonGroup.selectedButton]);
}
}
}
else {
result = [];
}// delete dialog box
myDialog.destroy;
if (result == []){
alert ("Operation cancelled");
exit();
}
else{
return result;
}
} -
August 26, 2022 at 3:29 pm #14371128
Theo de Klerk
ParticipantThis odd renumbering of list items seems a bug: https://indesign.uservoice.com/forums/913162-adobe-indesign-sdk-scripting-bugs-and-features/suggestions/38218423-scripting-graphiclayeroptions-changing-visibil
-
-
AuthorPosts
- The forum ‘General InDesign Topics (CLOSED)’ is closed to new topics and replies.
