How to paste clipboard into a channel using a photoshop script?

Viewed 78

I'm trying to create a image RGB or CMYK using separate greyscale documents for each channel. My current code copy all from greyscale document and paste in a new document creating a new layer for eachone. I don't want that, I want copy from each document and paste into eachone channels new document, same as manual way, selecting each channel and clicking Edit->paste->paste especial->paste in place.

// Loop to copy each separate channel into a new merged document
for (var doc_index = 0; doc_index < 3; doc_index++ ){
//Switch documents 
app.activeDocument = split_channels[0];

// copy active layer from separate channel document
app.activeDocument.selection.selectAll();
app.activeDocument.selection.copy();

// close document whithout save 
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

//select activeDocument
app.activeDocument = mergedDoc;

// reference to whole channels
//var channelIndex = doc_index;
var myChannels = app.activeDocument.channels;

// the channel must be visible to paste greyscale layer
myChannels[doc_index].visible= true;

// turn off the rest of channels    
for (var secondaryIndex = 0; secondaryIndex < myChannels.length; secondaryIndex++) {
    
    if (doc_index != secondaryIndex) {
        
        myChannels[secondaryIndex].visible= false
    }
}

//paste layer for each new document channel (no works correctly)
app.activeDocument.paste();
    
//reset the channel count after copy and close each document
var split_channels = app.documents;
}

thanks a lot for any suggestion

1 Answers

When copying the layer contents, you do want the layer contents to be visible so they are captured by the selection when you copy. When pasting, however, the destination of the selection is determined on the active layer/channel. Note that the document.activeChannels member requires an array when assigning to it, even if you are only wanting a single channel.

Also, be mindful of changing the underlying array while iterating over it (aka closing documents before exiting the for-loop). In my code below, I'm specifically iterating over a reference array, instead of the actual app.documents collection, to ensure the length of my array doesn't change when a document is closed.

For the sake of brevity, the following code assumes all documents are of equal dimensions/color modes/resolutions, the three source documents are flattened, and there's at least one pixel on each opposite extremity of the canvas to ensure the size/position is the same after pasting.

const colorMode = NewDocumentMode.RGB;
const numChannels = 3;

var srcDocs = new Array();
if (app.documents.length == numChannels) {
    for (var i = 0; i < app.documents.length; i++)
        srcDocs.push(app.documents[i]);
} else throw new Error("Channel merging for " + colorMode + " requires " + numChannels + " source documents.");

var doc = app.activeDocument;
var destDoc = app.documents.add(doc.width, doc.height, doc.resolution, "mergedDoc", colorMode);

var destChannels = new Array();
for (var i = 0; i < numChannels; i++)
    destChannels.push(destDoc.channels[i]);

for (var i in srcDocs) {
    // copy
    app.activeDocument = srcDocs[i];
    app.activeDocument.selection.selectAll();
    app.activeDocument.selection.copy();
    app.activeDocument.selection.deselect();
    app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);

    // pasta
    app.activeDocument = destDoc;
    var targetChannels = [destChannels[i]];
    app.activeDocument.activeChannels = targetChannels;
    app.activeDocument.paste();
}

app.activeDocument.selection.deselect();
app.activeDocument.activeChannels = destChannels;

enter image description here

Related