Skip to main content
Antonio Rebollo
New Participant
September 9, 2020
Answered

Photoshop script. Replace layers from another opened document.

  • September 9, 2020
  • 4 replies
  • 3681 views

Hi all!
I am starting with Photoshop scripting and I am not sure if the functionality I want to achieve is possible or not. It would be awesome if an experienced user could take a look and confirm, and if so, point me in the direction.

Basically I want to replace the layer "LayerA.001" in the targetDocument with the layer "LayerA.002" contained in the sourceDocument.psd, and so on with LayerB.001, C.001, D.001...
Now I can copy layers from one document to another but I can't locate specific layers by name using wildcards and replace them.
The targetDocument.psd contains a real scenario case(layers are duplicated, contained nested groups, clipped adjustment layers..) and the sourceDocument.psd contains the updated versions of these layers to be updated.
I understand that both documents must be open simultaneously, and one of both specifically must be in focus to work. Also, as HardMode, ti would be fantastic to keep the new name in replaced layers (in this sample xxxxx.002).

I provided the two sample files. My photoshop is CS6, I know is quite old, but works for our purposes. 

Thank you very much, in advance for the help!!

This topic has been closed for replies.
Correct answer c.pfaffenbichler

Here is some code to help identify the Layers in two open files that have the same names except for numbers after a dot at the end of the Layer’s name. 

 

// 2020, use it at your own risk;
var theRegExp = /(.*)\.[^\.]+$/;
// do stuff;
if (app.documents.length == 2) {
var theDocs = app.documents;
var theTarget = app.activeDocument;
if (theDocs[0] == theTarget) {var theSource = theDocs[1]}
else {var theSource = theDocs[0]};
// get layers;
var theTargetLayers = collectLayersNamesIndexAndIdentifier();
app.activeDocument = theSource;
var theSourceLayers = collectLayersNamesIndexAndIdentifier();
app.activeDocument = theTarget;
// process the layers;
var theResults = new Array;
for (var m = 0; m < theTargetLayers.length; m++) {
    if (theTargetLayers[m][0].indexOf(".")!=-1) {var targetName = theTargetLayers[m][0].match(theRegExp)[1]}
    else {var targetName = theTargetLayers[m][0]};
    for (var n = 0; n < theSourceLayers.length; n++) {
        if (theSourceLayers[n][0].indexOf(".")!=-1) {var sourceName = theSourceLayers[n][0].match(theRegExp)[1]}
        else {var sourceName = theSourceLayers[n][0]};
        if (targetName == sourceName) {
            theResults.push([theTargetLayers[m], theSourceLayers[n]])
        }
    }
};
alert ("the corresponding layers are\n"+theResults.join("\n"));
};
////// collect layers //////
function collectLayersNamesIndexAndIdentifier () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
var theKind = layerDesc.getInteger(stringIDToTypeID("layerKind"));
// if group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
theLayers.push([theName, theIndex, theID, theKind])
};
}
catch (e) {};
};
return theLayers
};

 

 

4 replies

c.pfaffenbichler
c.pfaffenbichlerCorrect answer
Community Expert
September 14, 2020

Here is some code to help identify the Layers in two open files that have the same names except for numbers after a dot at the end of the Layer’s name. 

 

// 2020, use it at your own risk;
var theRegExp = /(.*)\.[^\.]+$/;
// do stuff;
if (app.documents.length == 2) {
var theDocs = app.documents;
var theTarget = app.activeDocument;
if (theDocs[0] == theTarget) {var theSource = theDocs[1]}
else {var theSource = theDocs[0]};
// get layers;
var theTargetLayers = collectLayersNamesIndexAndIdentifier();
app.activeDocument = theSource;
var theSourceLayers = collectLayersNamesIndexAndIdentifier();
app.activeDocument = theTarget;
// process the layers;
var theResults = new Array;
for (var m = 0; m < theTargetLayers.length; m++) {
    if (theTargetLayers[m][0].indexOf(".")!=-1) {var targetName = theTargetLayers[m][0].match(theRegExp)[1]}
    else {var targetName = theTargetLayers[m][0]};
    for (var n = 0; n < theSourceLayers.length; n++) {
        if (theSourceLayers[n][0].indexOf(".")!=-1) {var sourceName = theSourceLayers[n][0].match(theRegExp)[1]}
        else {var sourceName = theSourceLayers[n][0]};
        if (targetName == sourceName) {
            theResults.push([theTargetLayers[m], theSourceLayers[n]])
        }
    }
};
alert ("the corresponding layers are\n"+theResults.join("\n"));
};
////// collect layers //////
function collectLayersNamesIndexAndIdentifier () {
// the file;
var myDocument = app.activeDocument;
// get number of layers;
var ref = new ActionReference();
ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
var theLayers = new Array;
for (var m = 0; m <= theNumber; m++) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
var theKind = layerDesc.getInteger(stringIDToTypeID("layerKind"));
// if group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var theName = layerDesc.getString(stringIDToTypeID('name'));
var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
var theIndex = layerDesc.getInteger(stringIDToTypeID('itemIndex'));
theLayers.push([theName, theIndex, theID, theKind])
};
}
catch (e) {};
};
return theLayers
};

 

 

Antonio Rebollo
New Participant
September 15, 2020

Thank you very much! This is gold to me 😄
I'll work with it. This is a great start point to put me on right track.


Thanks again!!

c.pfaffenbichler
Community Expert
September 15, 2020

I thaught of something, though. 

It would be possible that one layer in the one file references several layers in the other if the layers’ names were identical or similar enough … 

c.pfaffenbichler
Community Expert
September 10, 2020

Are there only going to be the two images open or do they have to be identified? 

What is the naming convention identifying the two corresponding files? 

c.pfaffenbichler
Community Expert
September 9, 2020

»TargetDocument.psd« seems to contain several Layers that are copies of the Layers in question. 

In my opinion those should usually all be Smart Object instances and not independet Layers – or is there a particular reason for this? 

Antonio Rebollo
New Participant
September 9, 2020

Thank you very much for your fast answer. Photoshop CS6 does have SmartObjects, but not LinkedSmartObjects.
You are completely right, the copy of a layer should be a copy of a smart object actually. The reason behind this is we work in a fast-pace iterations, where a certain update version might be live for a few hours only. That develop on us the bad habit of not creating smart-objects and just replace the layer (which we never modifiy as a non-destructive workflow). Also the chance of finding a copy of a layer in our files is low, but still exists, that is why I made it in the demo files.
For the love of simplicity, it would be good enough if I can replace a normal layer by name with wildcards. However, if it is better or simplier to use smartobjects, that is fine too.
Thank you!!

JJMack
Community Expert
September 9, 2020

I started scripting places smart object layers in CS2 so CS6 has smart object layers.  Replacing Smart object content can be very difficult.  Normal images can have their pixels changed by normals Photoshop tools but the only tool I know the will replace one image with and other is the clone stamp tool  and you really do not want to try to use tool recording.  IMO that feature was never implemented well it full of problems.  You better off deleting the layer you want replaced and pasting in the layer you want. 

 

Getting back to smart Object layers.  Why is it difficult to replace a smart objects layers object after all Photoshop has a such a feature menu Layer>Smart Objects>Replace Contents.   Heck its easy to replace a smart object layer content. Yes it is.  The rub is will that have the desired results. The answer is sometimes it may.

 

Let me explain a little more Photoshop will have no problem replacing a smart object layers content with the content of any support file type you choose  that has any size. Is that what you want? It may be or may not be.  And if it is what you want will it be like you want.   Its a complex issue.   If the the Smart object layer is in a template of some kind like a collage or product.  In general you do not want the object replaces with any odd size object.  For the Smart object layer is being used in a very specific output composite and is probably masked to  a specific are in the composite and the object should be sized for the area.   So when it comes to Templates Replacement should or must be the same size as the object in the template.  If replace the object in the template with a different size object you have most likely broken the template if you save it with the wrong size replacement in the template.

 

An other thing about a smart object layer is the object pixels are set in concrete and are not the pixels in the documents smart object layer.  A transformation of the object pixels are the actual layers pixels that may include warping the user added to the transform the subject matter for the document composite. This is not a destructive transform like on a normal layer. The transform is recorded for the object into the layer and can be edited the user. The transforming will always be fro the hardened objects pixels.

 

So even if you want to replace a small mouse with a large big fat rat if the mouse was was being positioned and warped for the original compost will the warping and position of the rat be what you want. When you replace the content of a smarts object layer how would Photoshop know how you would want the position and warping changed in the layers recorded transform for this different sized object.

 

Replacing a smart object is not simply menu layer>Smart Objects>Replace content.

 

Editing the Smart object you can fit the replacement into the original object canvas and not change its size just update the original object with new content.. However there is a run there too. Not all objects are Photoshop object. Photoshop does not support Camera Raw file Object and Vector Objects. These object will open is ACR or AI your script will loose control of the process and not be able to edit these Smart object. Photoshop script can nor Edit smart objects that are Vector and Camera RAW objects.

 

In general I think you would want document toe be independent therefore embedded smart objects  Linked object I think would be more business related  where you want to keep your logo or something updated everywhere,  Still the linked object process is not Automated.  You need to open assets with link object in Photoshop for Photoshop to update the objects. If you do not open the document in Photoshop they still contains your old content.  So you need to book keep what is used where so when you updated your logo  you know which assets need to be opened so they get updated.

JJMack
c.pfaffenbichler
Community Expert
September 9, 2020

That sounds like a task best performed with Smart Objects, possibly even linked Smart Objects. 

Did Photoshop CS6 have those?