Copy link to clipboard
Copied
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
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.
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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
hideOthers (theLayers
for (var n = 0; n < 3; n++) {
var theChannel = myDocument.channels
};
hideOthers (theLayers
};
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
count++;
if (theOriginal != false) {
theCopy.layers
}
};
};
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 );
};
Copy link to clipboard
Copied
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*...