Search code examples
scriptingphotoshopjsxphotoshop-script

Photoshop script to duplicate and rename layer


While creating a script that would automate all the different tasks I do when I start working on a new picture on Photoshop, I encountered the following problem.

I want to create different groups and different layers inside these groups. Everything goes perfectly fine until this :

#target photoshop

app.bringToFront();

var doc = app.activeDocument;

newCurve();

var clippingHelpLayerLight = doc.activeLayer;
clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
clippingHelpLayerLight.name = "Clipping Help Layer - Light";
clippingHelpLayerLight.visible = false;
clippingHelpLayerLight.duplicate();

var clippingHelpLayerLighter = doc.activeLayer;
clippingHelpLayerLighter.name = "Clipping Help Layer - Lighter";
clippingHelpLayerLighter.visible = false;

function newCurve() {
    var c_ADJ_LAYER = charIDToTypeID("AdjL");
    var c_ADJUSTMENT = charIDToTypeID("Adjs");
    var c_CHANNEL = charIDToTypeID("Chnl");
    var c_COMPOSITE = charIDToTypeID("Cmps");
    var c_CURVE = charIDToTypeID("Crv ");
    var c_CURVE_A = charIDToTypeID("CrvA");
    var c_CURVES = charIDToTypeID("Crvs");
    var c_HORIZONTAL = charIDToTypeID("Hrzn");
    var c_MAKE = charIDToTypeID("Mk  ");
    var c_NULL = charIDToTypeID("null");
    var c_POINT = charIDToTypeID("Pnt ");
    var c_TYPE = charIDToTypeID("Type");
    var c_USING = charIDToTypeID("Usng");
    var c_VERTICAL = charIDToTypeID("Vrtc");

    var d_CURVES_LAYER = new ActionDescriptor();
    // Contains all the information necessary to perform the "MAKE" action
    var r_CLASS = new ActionReference();
    r_CLASS.putClass(c_ADJ_LAYER);
    d_CURVES_LAYER.putReference(c_NULL, r_CLASS);
    // Class of make action is of an ajdustment layer
    var d_TYPE_CURVES = new ActionDescriptor();
    // Contains all the information about all the curves
    var d_CHANNEL_CURVES = new ActionDescriptor();
    var l_CHANNEL_CURVES = new ActionList();
    // Contains a list of channel curves
    var d_CHANNEL_CURVE = new ActionDescriptor();
    // Information for 1 channel curve
    var r_CHANNEL = new ActionReference();
    r_CHANNEL.putEnumerated(c_CHANNEL, c_CHANNEL, c_COMPOSITE);
    // This curve is for the composite channel - VARIES
    d_CHANNEL_CURVE.putReference(c_CHANNEL, r_CHANNEL);
    // Contains the point list
    var l_POINTS = new ActionList();
    // List of points for this channel - LENGTH VARIES
    var d_POINT = new ActionDescriptor();
    // One point on the curve, has INPUT and OUTPUT value
    d_POINT.putDouble(c_HORIZONTAL, 0.000000);
    d_POINT.putDouble(c_VERTICAL, 0.000000);
    l_POINTS.putObject(c_POINT, d_POINT);
    //var d_POINT3 = new ActionDescriptor();
    d_POINT.putDouble(c_HORIZONTAL, 255.000000);
    d_POINT.putDouble(c_VERTICAL, 255.000000);
    l_POINTS.putObject(c_POINT, d_POINT);
    // Made the list of points
    d_CHANNEL_CURVE.putList(c_CURVE, l_POINTS);
    // Now have a list of points for a specific channel
    l_CHANNEL_CURVES.putObject(c_CURVE_A, d_CHANNEL_CURVE);
    // Add to the list of channel curves
    d_CHANNEL_CURVES.putList(c_ADJUSTMENT, l_CHANNEL_CURVES);
    // All the channel curves are inside here
    d_TYPE_CURVES.putObject(c_TYPE, c_CURVES, d_CHANNEL_CURVES);
    // .....
    d_CURVES_LAYER.putObject(c_USING, c_ADJ_LAYER, d_TYPE_CURVES);
    // package the curves and definition of the adjustment layer type
    executeAction(c_MAKE, d_CURVES_LAYER, DialogModes.NO);
}

I actually want to create a first layer called "Clipping Help Layer - Light", blend mode : screen and turn it off. Then duplicate it, change the name of the new layer as "Clipping Help Layer - Lighter" and turn it off too.

Like this : Screenshot of what I would like to do

It does create the 2 layers, but the first one has " copy" at the end of its name and it stays turned on.

Screenshot of the actual result

Why ?

I can't understand why it doesn't work as expected and can't manage to fix it.

Any help would be greatly appreciated !


Solution

  • I believe the problem you are encountering has to do with doc.activeLayer. After you duplicate "Clipping Help Layer - Light," the script does not seem to change what doc.activeLayer is pointing to so when you then try to assign it to clippingHelpLayerLighter, you are then pointing at an undefined layer. While I don't know exactly what is happening behind the scenes when you do that, I do believe this will fix your problem:

    #target photoshop
    
    app.bringToFront();
    
    var doc = app.documents.add( 4, 4 );
    
    doc = app.activeDocument;
    
    var clippingHelpLayerLight = doc.activeLayer;
    clippingHelpLayerLight.blendMode = BlendMode.SCREEN;
    clippingHelpLayerLight.name = "Clipping Help Layer - Light";
    clippingHelpLayerLight.visible = false;
    clippingHelpLayerLight.duplicate();
    
    doc.activeLayer = doc.layers[ "Clipping Help Layer - Light copy" ];
    doc.activeLayer.name = "Clipping Help Layer - Lighter";
    doc.activeLayer.visible = false;
    
    //I am not sure if you need this pointer to be called upon later in your 
    //code. If you do not, just leave this line out.
    var clippingHelpLayerLighter = doc.activeLayer;
    

    Hope this helps! Let me know if you have any questions, I'm by no means an expert but I use scripts fairly often.