Skip to main content
Inspiring
September 5, 2011
Answered

clone stamp on multiple layers/images at once

  • September 5, 2011
  • 2 replies
  • 1606 views

Hi everyone,

I'd like to know wheter anyone knows a way or workaround to use brushes/clone stamp on multiple layers or images at once.

For days i have read in forums about that topic but could not find a solution. Actions wont work as they do not record brush strokes. I even tried a mouse recorder, but the free one i downloaded does only save the position of the click and the mouse release, turning every curve into a straight line.

Any thoughts/ideas?

I do not quite understand why I cannot find a function to brush/stamp/smudge on all selected layers.

Thanks and best Regards,

Martin

Edit: sry probably should have posted that in Photoshop Windows

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

One workaround is to use a multichannel file and after clone stamping re-converting those channels to their proper places in rgb-layers.

I once did a Script for that but that was only for use on solid layers, as the transparency issues would be a bit too much for me.

2 replies

Inspiring
October 14, 2011

Thank you so much, this solution is exactly what i was looking for .

Fun fact, i did not understand your answer at first until after i figured it out myself a few days ago *head-against-wall*...

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
September 5, 2011

One workaround is to use a multichannel file and after clone stamping re-converting those channels to their proper places in rgb-layers.

I once did a Script for that but that was only for use on solid layers, as the transparency issues would be a bit too much for me.

c.pfaffenbichler
Community Expert
Community Expert
September 8, 2011

This is not exhaustively tested and it will change the appearance somewhat when switching to multichannel – but when re-transfering the edited content the appearance should change back.

If you want to give it a try:

// moves copy of rgb file to multichannel or multichannel file to rgb;

// tries to move layer back to the file and path in the file info of the multichannel copy;

// transparencies are disregarded and will be lost;

// be advised: only useful for clone stamping and healing brush;

// cs5 on macintosh:

// 2011, pfaffenbichler, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var mode = app.activeDocument.mode;

switch (mode) {

     case DocumentMode.RGB:

     RGBToMultichannel ();

     break;

     case DocumentMode.MULTICHANNEL:

     multiChannelToRGB ()

     break;

     default:

     alert ("please open an rgb-file with more than one layer or a multichannel-file with a multiple of three channels")

     break;

     };

////////////////////////////////////

}

else {

alert ("please open an rgb-file with more than one layer or a multichannel-file with a multiple of three channels")

};

////////////////////////////////////

////////////////////////////////////

////////////////////////////////////

////// operate on rgb file //////

function RGBToMultichannel () {

var myDocument = app.activeDocument;

// make certain there is more than one pixel layer;

var theLayers = collectPixelLayers (myDocument);

hideOthers (theLayers[0], myDocument);

////////////////////////////////////

if (theLayers.length > 1) {

// make copy and convert;

     var theCopy = myDocument.duplicate("theCopy_"+myDocument.name);

     multiChannel ();

     var theMessage = ["multiChannelAndBack",myDocument.name,myDocument.path, removeSemicolons(theLayers[0].name)];

// remove additional channels;

     while (theCopy.channels.length > 3) {

          theCopy.channels[theCopy.channels.length - 1].remove()

          };

// back to original;

     app.activeDocument = myDocument;

     hideOthers (theLayers[0], myDocument);

// insert other channels;

     for (var m = 1; m < theLayers.length; m++) {

          theMessage.push(removeSemicolons(theLayers.name));

          hideOthers (theLayers, myDocument);

          for (var n = 0; n < 3; n++) {

               var theChannel = myDocument.channels.duplicate(theCopy);

               };

          hideOthers (theLayers, myDocument);

          };

     app.activeDocument = theCopy;

// array of array for spot colors;

     var theColorArray = [[100,0,0,0], [0,100,0,0], [0,0,100,0]];

// make spot channel and set to color;

     for (var q = 1; q < theLayers.length; q++) {

          for (var r = 0; r < 3; r++) {

               var theChannel = theCopy.channels[q * 3 + r];

               theCopy.activeChannels = [theChannel];

               theChannel.kind = ChannelType.SPOTCOLOR;

               changeSpot(theColorArray);

               }

          };

// make channels active;

     var theChannels = new Array;

     for (var o = 0; o < theLayers.length * 3; o++) {

          theChannels.push(theCopy.channels)

          };

     theCopy.activeChannels = theChannels;

// hide all but the first three channels;

     for (var p = 3; p < theLayers.length * 3; p++) {

          theCopy.channels

.visible = false

          };

// insert message in file info;

     infoDescription(theMessage.join(";"));

     }

else {

     alert ("please open an rgb-file with more than one layer")

     };

};

////// operate on multochannel file //////

function multiChannelToRGB () {

var thisDocument = app.activeDocument;

////////////////////////////////////

if (thisDocument.channels.length >= 6 && String(thisDocument.channels.length / 3).indexOf(".") == -1) {

// make copy and change to rgb but don’t color manage;     

     var theCopy = thisDocument.duplicate("theBackCopy");

     modeRGB ();

     dontColorManage();

// get message;

     var theMessage = theCopy.info.caption.split(";");

// set colors;

     var white = new SolidColor;

     white.hsb.hue = 0;

     white.hsb.saturation = 0;

     white.hsb.brightness = 100;

     var black = new SolidColor;

     black.hsb.hue = 0;

     black.hsb.saturation = 0;

     black.hsb.brightness = 0;

// insert other channels;

     for (var m = 1; m < theCopy.channels.length / 3; m++) {

          theCopy.selection.selectAll();

          var theLayer = theCopy.artLayers.add();

          theCopy.activeLayer  = theLayer;

          theCopy.selection.fill(white);

          for (var n = 0; n < 3; n++) {

               theCopy.selection.load(theCopy.channels[m * 3 + n], SelectionType.REPLACE, false);

               theCopy.activeChannels = [theCopy.channels];

               theCopy.selection.fill(black);

               };

          };

     theCopy.activeChannels = [theCopy.channels[0], theCopy.channels[1], theCopy.channels[2]];

     theCopy.selection.deselect();

// look for original file;

          var theOriginal = false;

          for (var p = 0; p < app.documents.length; p++) {

               if (app.documents

.name == theMessage[1] && app.documents

.path == theMessage[2]) {

                    var theOriginal = app.documents

                    }

               };

          if (theOriginal == false && File(theMessage[2]+"/"+theMessage[1]).exists == true) {

               var theOriginal = app.open(File(theMessage[2]+"/"+theMessage[1]))

               };

          app.activeDocument = theCopy;

// rename the layers and try to move them back;

     if (theMessage[0] == "multiChannelAndBack") {

          var count = 3;

          for (var o = theCopy.layers.length - 1; o >= 0; o--) {

               theCopy.layers.name = theMessage[count] + "_edited";

               count++;

               if (theOriginal != false) {

                    theCopy.layers.duplicate(theOriginal, ElementPlacement.PLACEATBEGINNING);

                    }

               };

          };

     if (theOriginal != false) {theCopy.close(SaveOptions.DONOTSAVECHANGES)};

     }

else {

     alert ("please open an multichannel-file with a multiple of three channels")

     };

};

////////////////////////////////////

////////////////////////////////////

////////////////////////////////////

////// function collect all layers //////

function collectPixelLayers (theParent) {

     if (!allLayers) {

          var allLayers = new Array}

     else {};

     for (var m = theParent.layers.length - 1; m >= 0;m--) {

          var theLayer = theParent.layers;

// apply the function to layersets;

          if (theLayer.typename == "ArtLayer") {

// collect only pixel layers;

               if (theLayer .kind == LayerKind.NORMAL) {

                    theLayer.visible = true;

                    allLayers.push(theLayer)

                    }

               }

          else {

               allLayers = allLayers.concat(collectPixelLayers (theLayer))

// this line includes the layer groups;

//               allLayers.push(theLayer);

               }

          }

     return allLayers

     };

////// function convert to multichannel //////

function multiChannel () {

var idCnvM = charIDToTypeID( "CnvM" );

var desc117 = new ActionDescriptor();

var idT = charIDToTypeID( "T   " );

var idMltC = charIDToTypeID( "MltC" );

desc117.putClass( idT, idMltC );

executeAction( idCnvM, desc117, DialogModes.NO );

};

////// toggle visibility of others //////

function hideOthers (theLayer, myDocument) {

myDocument.activeLayer = theLayer;

theLayer.visible = true;

// =======================================================

var idShw = charIDToTypeID( "Shw " );

    var desc10 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var list4 = new ActionList();

            var ref7 = new ActionReference();

            var idLyr = charIDToTypeID( "Lyr " );

            var idOrdn = charIDToTypeID( "Ordn" );

            var idTrgt = charIDToTypeID( "Trgt" );

            ref7.putEnumerated( idLyr, idOrdn, idTrgt );

        list4.putReference( ref7 );

    desc10.putList( idnull, list4 );

    var idTglO = charIDToTypeID( "TglO" );

    desc10.putBoolean( idTglO, true );

executeAction( idShw, desc10, DialogModes.NO );

};

////// description //////

function infoDescription (theString) {

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc2 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref1 = new ActionReference();

        var idPrpr = charIDToTypeID( "Prpr" );

        var idFlIn = charIDToTypeID( "FlIn" );

        ref1.putProperty( idPrpr, idFlIn );

        var idDcmn = charIDToTypeID( "Dcmn" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref1.putEnumerated( idDcmn, idOrdn, idTrgt );

    desc2.putReference( idnull, ref1 );

    var idT = charIDToTypeID( "T   " );

        var desc3 = new ActionDescriptor();

        var idCptn = charIDToTypeID( "Cptn" );

        desc3.putString( idCptn, theString );

    var idFlIn = charIDToTypeID( "FlIn" );

    desc2.putObject( idT, idFlIn, desc3 );

executeAction( idsetd, desc2, DialogModes.NO );

};

////// remove semicolons //////

function removeSemicolons(theString) {

while (theString.indexOf(";") != -1) {theString = theString.replace(";", "_")};

return theString

};

////// change spot channel //////

function changeSpot (theArray) {

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc13 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref4 = new ActionReference();

        var idChnl = charIDToTypeID( "Chnl" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref4.putEnumerated( idChnl, idOrdn, idTrgt );

    desc13.putReference( idnull, ref4 );

    var idT = charIDToTypeID( "T   " );

        var desc14 = new ActionDescriptor();

        var idNm = charIDToTypeID( "Nm  " );

        desc14.putString( idNm, theArray.join("_") );

        var idClr = charIDToTypeID( "Clr " );

            var desc15 = new ActionDescriptor();

            var idCyn = charIDToTypeID( "Cyn " );

            desc15.putDouble( idCyn, theArray[0] );

            var idMgnt = charIDToTypeID( "Mgnt" );

            desc15.putDouble( idMgnt, theArray[1] );

            var idYlw = charIDToTypeID( "Ylw " );

            desc15.putDouble( idYlw, theArray[2] );

            var idBlck = charIDToTypeID( "Blck" );

            desc15.putDouble( idBlck, theArray[3] );

        var idCMYC = charIDToTypeID( "CMYC" );

        desc14.putObject( idClr, idCMYC, desc15 );

        var idOpct = charIDToTypeID( "Opct" );

        var idPrc = charIDToTypeID( "#Prc" );

        desc14.putUnitDouble( idOpct, idPrc, 0 );

    var idSCch = charIDToTypeID( "SCch" );

    desc13.putObject( idT, idSCch, desc14 );

executeAction( idsetd, desc13, DialogModes.NO );

};

////// function collect all layers //////

function modeRGB () {

var idCnvM = charIDToTypeID( "CnvM" );

var desc114 = new ActionDescriptor();

var idT = charIDToTypeID( "T   " );

var idRGBM = charIDToTypeID( "RGBM" );

desc114.putClass( idT, idRGBM );

executeAction( idCnvM, desc114, DialogModes.NO );

};

////// function collect all layers //////

function dontColorManage () {

// =======================================================

var idassignProfile = stringIDToTypeID( "assignProfile" );

    var desc3 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref2 = new ActionReference();

        var idDcmn = charIDToTypeID( "Dcmn" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref2.putEnumerated( idDcmn, idOrdn, idTrgt );

    desc3.putReference( idnull, ref2 );

    var idmanage = stringIDToTypeID( "manage" );

    desc3.putBoolean( idmanage, false );

executeAction( idassignProfile, desc3, DialogModes.NO );

};