No announcement yet.

How can I create an adjustment layer using script ?!? ..and few more questions

  • Filter
  • Time
  • Show
Clear All
new posts

  • How can I create an adjustment layer using script ?!? ..and few more questions

    Hi I just started to make use of scripting for Photoshop.. and I have few.. issues I can't get through..
    1. How can I create an adjustment layer (like curves.. etc)?
    the following code doesn't do the job:

    var artLayerRef = app.activeDocument.artLayers.add();
    artLayerRef.kind = LayerKind.CURVES;

    it says that I can only change to normal or text layer.. how then I can right away create CURVES layer?? Is that possible?

    2. Can I make use of "Save for Web" option from File menu (it is possible with Actions)? I noticed only the option to use standard save as jpg... which is not so good in some cases..

    3. .. can I use scripts to run photoshop actions.. (in case of some disabilities of scripting which actions can go through.. hope there's none.. ?
    Sorry if my issues are simply silly but I'm completely newbie to PS scripting.. and quite fresh to scripting at all.. I've just spend few hours trying to create simple solid color layer using script.. with no success Thanks for help..

  • #2


    I don't do scripting per se, but I believe I read somewhere the command DoAction is the one for invoking actions in a script. The command acts as "a call," that is once the action completes (assuming successfully) control returns to the script and the next command in the script is executed.

    Gotta pass on the others. Way out of my league.



    • #3
      Yes, Danny is right.

      The silly thing is that I discovered this after I wrote my own doAction

      There are a number of things scripting cannot do, among them creating adjustment layers and layer masks. You must create an action for it and then perform that action from the script.

      When you run into this situation, try to think of other ways to do it. There often are.


      • #4
        You can do everything you want without dependencies on calling actions the end user may or may not have by using the "Scripting Listener Plug-In" that comes with Photoshop. The scripting listener basically records actions as Javascript that can be integrated right into your script.


        • #5
          Now if this is correct... :-)

          Originally posted by T-Berry
          You can do everything you want without dependencies on calling actions the end user may or may not have by using the "Scripting Listener Plug-In" that comes with Photoshop.
          I tried the Scripting Listener briefly, but it only logged stuff I already knew how to do myself. So I turned away, disappointed. It never occurred to me that it might be able to log code for creating adjustement layers. Does it really? I don't have time to test this for myself right now


          • #6
            You can definitely do adjustment layers using the listener plug-in. It isn't pretty code or easy to decifer though:
            function adjCurve(){
            	var id18 = charIDToTypeID( "Mk  " );
            		var desc3 = new ActionDescriptor();
            		var id19 = charIDToTypeID( "null" );			      var ref1 = new ActionReference();
            			var id20 = charIDToTypeID( "AdjL" );
            			ref1.putClass( id20 );
            		desc3.putReference( id19, ref1 );
            		var id21 = charIDToTypeID( "Usng" );
            			var desc4 = new ActionDescriptor();
            			var id22 = charIDToTypeID( "Type" );
            				var desc5 = new ActionDescriptor();
            				var id23 = charIDToTypeID( "Adjs" );
            					var list1 = new ActionList();
            						var desc6 = new ActionDescriptor();
            						var id24 = charIDToTypeID( "Chnl" );
            							var ref2 = new ActionReference();
            							var id25 = charIDToTypeID( "Chnl" );
            							var id26 = charIDToTypeID( "Chnl" );
            							var id27 = charIDToTypeID( "Cmps" );
            							ref2.putEnumerated( id25, id26, id27 );
            						desc6.putReference( id24, ref2 );
            						var id28 = charIDToTypeID( "Crv " );
            							var list2 = new ActionList();
            								var desc7 = new ActionDescriptor();
            								var id29 = charIDToTypeID( "Hrzn" );
            								desc7.putDouble( id29, 0.000000 );
            								var id30 = charIDToTypeID( "Vrtc" );
            								desc7.putDouble( id30, 0.000000 );
            							var id31 = charIDToTypeID( "Pnt " );
            							list2.putObject( id31, desc7 );
            								var desc8 = new ActionDescriptor();
            								var id32 = charIDToTypeID( "Hrzn" );
            								desc8.putDouble( id32, 95.000000 );
            								var id33 = charIDToTypeID( "Vrtc" );
            								desc8.putDouble( id33, 147.000000 );
            							var id34 = charIDToTypeID( "Pnt " );
            							list2.putObject( id34, desc8 );
            								var desc9 = new ActionDescriptor();
            								var id35 = charIDToTypeID( "Hrzn" );
            								desc9.putDouble( id35, 255.000000 );
            								var id36 = charIDToTypeID( "Vrtc" );
            								desc9.putDouble( id36, 255.000000 );
            							var id37 = charIDToTypeID( "Pnt " );
            							list2.putObject( id37, desc9 );
            						desc6.putList( id28, list2 );
            					var id38 = charIDToTypeID( "CrvA" );
            					list1.putObject( id38, desc6 );
            				desc5.putList( id23, list1 );
            			var id39 = charIDToTypeID( "Crvs" );
            			desc4.putObject( id22, id39, desc5 );
            		var id40 = charIDToTypeID( "AdjL" );
            		desc3.putObject( id21, id40, desc4 );
            	executeAction( id18, desc3, DialogModes.NO );
            In the above example, there is one point on the curve using the input 95 and changing it's output to 147. You could make these variables and drop your own values in there. If you needed more points, just use the listener to record and adjustment layer curve with more points.

            Here is how you use the listener to create a GIF from save for web. I've made the file path, lossy, dither and # of colors in the gif variables and passed them in when I call the function:

            	function S4W_GIF(filePath, randomLoss, randomDither, randomColortableGIF){
            		var id238 = charIDToTypeID( "Expr" );
            	    	var desc37 = new ActionDescriptor();
            	   	var id239 = charIDToTypeID( "Usng" );
            	        var desc38 = new ActionDescriptor();
            	        var id240 = charIDToTypeID( "Op  " );
            	        var id241 = charIDToTypeID( "SWOp" );
            	        var id242 = charIDToTypeID( "OpSa" );
            	        desc38.putEnumerated( id240, id241, id242 );
            	        var id243 = charIDToTypeID( "Fmt " );
            	        var id244 = charIDToTypeID( "IRFm" );
            	        var id245 = charIDToTypeID( "GIFf" );
            	        desc38.putEnumerated( id243, id244, id245 );
            	        var id246 = charIDToTypeID( "Intr" );
            	        desc38.putBoolean( id246, false );
            	        var id247 = charIDToTypeID( "RedA" );
            	        var id248 = charIDToTypeID( "IRRd" );
            	        var id249 = charIDToTypeID( "Sltv" );
            	        desc38.putEnumerated( id247, id248, id249 );
            	        var id250 = charIDToTypeID( "RChT" );
            	        desc38.putBoolean( id250, false );
            	        var id251 = charIDToTypeID( "RChV" );
            	        desc38.putBoolean( id251, false );
            	        var id252 = charIDToTypeID( "AuRd" );
            	        desc38.putBoolean( id252, false );
            	        var id253 = charIDToTypeID( "NCol" );
            	        desc38.putInteger( id253, randomColortableGIF );
            	        var id254 = charIDToTypeID( "Dthr" );
            	        var id255 = charIDToTypeID( "IRDt" );
            	        var id256 = charIDToTypeID( "Dfsn" );
            	        desc38.putEnumerated( id254, id255, id256 );
            	        var id257 = charIDToTypeID( "DthA" );
            	        desc38.putInteger( id257, randomDither );
            	        var id258 = charIDToTypeID( "DChS" );
            	        desc38.putInteger( id258, 0 );
            	        var id259 = charIDToTypeID( "DCUI" );
            	        desc38.putInteger( id259, 0 );
            	        var id260 = charIDToTypeID( "DChT" );
            	        desc38.putBoolean( id260, false );
            	        var id261 = charIDToTypeID( "DChV" );
            	        desc38.putBoolean( id261, false );
            	        var id262 = charIDToTypeID( "WebS" );
            	        desc38.putInteger( id262, 0 );
            	        var id263 = charIDToTypeID( "TDth" );
            	        var id264 = charIDToTypeID( "IRDt" );
            	        var id265 = charIDToTypeID( "None" );
            	        desc38.putEnumerated( id263, id264, id265 );
            	        var id266 = charIDToTypeID( "TDtA" );
            	        desc38.putInteger( id266, 100 );
            	        var id267 = charIDToTypeID( "Loss" );
            	        desc38.putInteger( id267, randomLoss);
            	        var id268 = charIDToTypeID( "LChS" );
            	        desc38.putInteger( id268, 0 );
            	        var id269 = charIDToTypeID( "LCUI" );
            	        desc38.putInteger( id269, 100 );
            	        var id270 = charIDToTypeID( "LChT" );
            	        desc38.putBoolean( id270, false );
            	        var id271 = charIDToTypeID( "LChV" );
            	        desc38.putBoolean( id271, false );
            	        var id272 = charIDToTypeID( "Trns" );
            	        desc38.putBoolean( id272, true );
            	        var id273 = charIDToTypeID( "Mtt " );
            	        desc38.putBoolean( id273, true );
            	        var id274 = charIDToTypeID( "MttR" );
            	        desc38.putInteger( id274, 255 );
            	        var id275 = charIDToTypeID( "MttG" );
            	        desc38.putInteger( id275, 255 );
            	        var id276 = charIDToTypeID( "MttB" );
            	        desc38.putInteger( id276, 255 );
            	        var id277 = charIDToTypeID( "SHTM" );
            	        desc38.putBoolean( id277, false );
            	        var id278 = charIDToTypeID( "SImg" );
            	        desc38.putBoolean( id278, true );
            	        var id279 = charIDToTypeID( "SSSO" );
            	        desc38.putBoolean( id279, false );
            	        var id280 = charIDToTypeID( "SSLt" );
            	        var list3 = new ActionList();
            	        desc38.putList( id280, list3 );
            	        var id281 = charIDToTypeID( "DIDr" );
            	        desc38.putBoolean( id281, false );
            	        var id282 = charIDToTypeID( "In  " );
            	        desc38.putPath( id282, new File( filePath ) );
            	   	var id283 = stringIDToTypeID( "SaveForWeb" );
            	  	desc37.putObject( id239, id283, desc38 );
            		executeAction( id238, desc37, DialogModes.NO );
            S4W_GIF( "~/Desktop/" , 50, 50, 255);


            • #7
              Re: How can I create an adjustment layer using script ?!? ..and few more questions

              Even though this is an old thread, the topic is still one that evokes questions.

              QUESTION: If you can't (for example) create a Hue/Saturation Adjustment Layer from Javascript, then why (oh, why) does the JavaScript Reference Guide CS3 show a LayerKind.HUESATURATION (pg272)?

              Has anyone figured out how to create this (in strict Javascript) without the Script Listener?

              Any help is appreciated.


              • #8
                Re: How can I create an adjustment layer using script ?!? ..and few more questions


                1) Yes, you can create any type of adjustment layer in JS.
                2) Yes, you can do without ScriptListener - if you copy the code from someplace else. Although it will still have the general form as TBerry posted.

                This is a "decompiled" version of a curves layer that I did starting from the ScriptListener output.
                Even after identifying all the components, it still doesn't make for easy reading.

                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_POINT2 = new ActionDescriptor();
                								d_POINT.putDouble( c_HORIZONTAL, 100.000000 );
                								d_POINT.putDouble( c_VERTICAL, 80.000000 );
                							l_POINTS.putObject( c_POINT, d_POINT );
                								//var d_POINT2 = new ActionDescriptor();
                								d_POINT.putDouble( c_HORIZONTAL, 200.000000 );
                								d_POINT.putDouble( c_VERTICAL, 150.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 );


                • #9
                  Re: How can I create an adjustment layer using script ?!? ..and few more questions

                  Originally posted by Klaatu Baradda View Post
                  QUESTION: If you can't (for example) create a Hue/Saturation Adjustment Layer from Javascript, then why (oh, why) does the JavaScript Reference Guide CS3 show a LayerKind.HUESATURATION (pg272)?
                  All of the LayerKind types are there because you can write a script that needs to know that an existing layer is a HUESATURATION kind of layer even though you can't create one via the JS DOM.

                  As has been said before, you can write ActionDescriptor-based code to create whatever kind of layer you need. Some, like Exposure or Photo Filter, are fairly simple. Others, like Levels and Curves, and get a bit complicated.



                  Related Topics