3 Replies Latest reply on Sep 24, 2012 1:57 PM by Michael L Hale

    How do I control a layer's Bevel and Emboss effect's "highlight color" through a script?

    WebNola

      I have a script which loads colors from a .txt file which someone on this forum helped me with. It loads the colors into the file, and inerts them into four different layers, then saves with a filename which is also in the .txt file. It basically works great to change a solid color layer.

       

      Now, I want to add the functionality to add one more color to the equation, this color will be the layer's Bevel and Emboss effect's "highlight color". Can anyone please help?

       

      Here is the code I have, again it works great, I just want to add one more color to the equation but the syntax is confusing:

       

       

      #target photoshop

      if (app.documents.length > 0) {

      var myDocument = app.activeDocument;

      var documentName = myDocument.name;

      var basename = documentName.match(/(.*)\.[^\.]+$/)[1];

      // get path;

      try {var documentPath = myDocument.path}

      catch (e) {var documentPath = "~/Desktop"};

      // psd options, not using this anymore;

      psdOpts = new PhotoshopSaveOptions();

      psdOpts.embedColorProfile = true;

      psdOpts.alphaChannels = false;

      psdOpts.layers = true;

      psdOpts.spotColors = true;

      // jpg options

      jpgOptions = new JPEGSaveOptions();

      jpgOptions.embedColorProfile = true;

      jpgOptions.formatOptions = FormatOptions.STANDARDBASELINE;

      jpgOptions.matte = MatteType.NONE;

      jpgOptions.quality = 9;

      // get file;

      if ($.os.search(/windows/i) != -1) {var theFile = File.openDialog ("please select files", "*.txt", false)}

      else {var theFile = File.openDialog ("please select files", getFiles, false)};

      if (theFile) {

      var theText = readPref(theFile);

      var theArray = theText.split("\n");

      //

      try {

      var theLayer = myDocument.layers.getByName("colorLayer");

      var theOtherLayer = myDocument.layers.getByName("colorLayer2");

      var curveOne = myDocument.layers.getByName("TopCurve");

      var curveTwo = myDocument.layers.getByName("BottomCurve");

      // work through list;

      for (var m = 0; m < theArray.length; m++) {

      var thisText = theArray[m].split(";");

      // alert (thisText.join("\n\n"));

      var theName = thisText[0];

      editSolidFill (thisText[1], thisText[2], thisText[3], theLayer);

      editSolidFill (thisText[1], thisText[2], thisText[3], curveOne);

      editSolidFill (thisText[5], thisText[6], thisText[7], theOtherLayer);

      editSolidFill (thisText[9], thisText[10], thisText[11], curveTwo);

      // save psd;

      myDocument.saveAs((new File(documentPath+"/"+basename+"_"+theName+".jpg")),jpgOptions,true);

      }

      }

      catch (e) {};

      };

      };

      ////// function to change solid fill layers //////

      function editSolidFill (theL, theA, theB, theLayer) {

      app.activeDocument.activeLayer = theLayer;

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

      var idsetd = charIDToTypeID( "setd" );

          var desc3 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref2 = new ActionReference();

              var idcontentLayer = stringIDToTypeID( "contentLayer" );

              var idOrdn = charIDToTypeID( "Ordn" );

              var idTrgt = charIDToTypeID( "Trgt" );

              ref2.putEnumerated( idcontentLayer, idOrdn, idTrgt );

          desc3.putReference( idnull, ref2 );

          var idT = charIDToTypeID( "T   " );

              var desc4 = new ActionDescriptor();

              var idClr = charIDToTypeID( "Clr " );

                  var desc5 = new ActionDescriptor();

                  var idLmnc = charIDToTypeID( "Lmnc" );

                  desc5.putDouble( idLmnc, theL );

                  var idA = charIDToTypeID( "A   " );

                  desc5.putDouble( idA, theA );

                  var idB = charIDToTypeID( "B   " );

                  desc5.putDouble( idB, theB );

              var idLbCl = charIDToTypeID( "LbCl" );

              desc4.putObject( idClr, idLbCl, desc5 );

          var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

          desc3.putObject( idT, idsolidColorLayer, desc4 );

      executeAction( idsetd, desc3, DialogModes.NO );

      };

      ////// read prefs file //////

      function readPref (thePath) {

        if (File(thePath).exists == true) {

          var file = File(thePath);

          file.open("r");

          file.encoding= 'BINARY';

          var theText = new String;

          for (var m = 0; m < file.length; m ++) {

            theText = theText.concat(file.readch());

            };

          file.close();

          return String(theText)

          }

        };

      ////// get psds, tifs and jpgs from files //////

      function getFiles (theFile) {

          if (theFile.name.match(/\.(txt)$/i)) {

              return true

              };

                };

       

        • 1. Re: How do I control a layer's Bevel and Emboss effect's "highlight color" through a script?
          Michael L Hale Level 5

          Scripting changes to layer effects is not easy. The script below will let you change just the highlight color of the bevel and emboss effects while keeping all the other existing setting in that effect as well as any other effects that may be applied to the active layer.

           

           

          // helper function for working with descriptors
          function getActiveLayerProperty( psKey, psType ) {
                var ref;
                ref = new ActionReference();
                ref.putProperty( charIDToTypeID( 'Prpr' ), psKey );
                ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
                if( undefined == psType ){
                    return executeActionGet( ref ).getObjectValue( psKey );
              }else{
                  return executeActionGet( ref );
              }
          };
          function duplicateDescriptor( descriptor ) {
              var newDescriptor;
              newDescriptor = new ActionDescriptor;
              newDescriptor.fromStream( descriptor.toStream() );
              return newDescriptor;
          };
          function localizeDescriptor( desc ) {
              var stream, pointer, zStringLength, zstring, localized_string, newZStringLength, previousStream, followingStream, newDesc;
              stream = desc.toStream();
              while( true ) {
                  pointer = stream.search(/TEXT....\x00\$\x00\$\x00\$/);
                  if( pointer === -1 ) {
                      break;
                  }
                  zStringLength = getLongFromStream( stream, pointer + 4 );
                  zstring = readUnicode( stream.substr( pointer + 8, ( zStringLength - 1 ) * 2) );
                  localized_string = ( localize( zstring ) ) + '\u0000';
                  newZStringLength = localized_string.length;
                  previousStream = stream.slice( 0, pointer);
                  followingStream = stream.slice( pointer + 8 + zStringLength * 2);
                  stream = previousStream.concat( 'TEXT', longToString( newZStringLength ), bytesToUnicode( localized_string ), followingStream );
              }
              newDesc = new ActionDescriptor();
              newDesc.fromStream( stream );
              return newDesc;
          };
          function getShortFromStream( stream, pointer ) {
              var hi, low;
              hi = stream.charCodeAt( pointer ) << 8 ;
              low = stream.charCodeAt( pointer + 1 );
              return hi + low;
           };
          function getLongFromStream( stream, pointer ) {
              var hi, low;
              hi = getShortFromStream( stream, pointer) << 16;
              low = getShortFromStream( stream, pointer + 2);
              return hi + low;
          };
          function readUnicode( unicode ) {
              var string = "";
              for( i = pointer = 0; pointer < unicode.length; i = pointer += 2) {
                  string +=String.fromCharCode( getShortFromStream( unicode, pointer ) );
              }
              return string;
          };
          function longToString( longInteger ) {
              var string;
              string = String.fromCharCode( longInteger >>> 24 );
              string += String.fromCharCode( longInteger << 8 >>> 24 );
              string += String.fromCharCode( longInteger << 16 >>> 24 );
              string += String.fromCharCode( longInteger << 24 >>> 24 );
              return string;
          };
          function bytesToUnicode( bytes ) {
              var unicode = "", char_code, charIndex;
              for( charIndex  = 0; charIndex < bytes.length; charIndex ++ ) {
                  char_code = bytes.charCodeAt( charIndex );
                  unicode += String.fromCharCode(char_code >> 8 ) +  String.fromCharCode( char_code & 0xff );
              }
              return unicode;
          };
          // main functon to change just the highlight color in the bevel and emboss effect
          function setBevelEmbossHighlightColor( hilightColor ) {
              var layerEffects, newLayerEffects, currentBevelEmboss, newBevelEmboss, rgbColorDesc, newLayerEffects, layerDesc, targetDesc, setDesc;
              layerEffects = getActiveLayerProperty( charIDToTypeID( 'Lefx' ) );
              newLayerEffects = duplicateDescriptor( layerEffects );
              currentBevelEmboss = layerEffects.getObjectValue( charIDToTypeID( 'ebbl' ) );
              newBevelEmboss = duplicateDescriptor( currentBevelEmboss );
              rgbColorDesc = new ActionDescriptor();
                  rgbColorDesc.putDouble( charIDToTypeID( 'Rd  ' ), hilightColor.rgb.red );
                  rgbColorDesc.putDouble( charIDToTypeID( 'Grn ' ), hilightColor.rgb.green );
                  rgbColorDesc.putDouble( charIDToTypeID( 'Bl  ' ), hilightColor.rgb.blue );
              newBevelEmboss.putObject( charIDToTypeID( 'hglC' ), charIDToTypeID( 'RGBC' ), rgbColorDesc );
              newLayerEffects.putObject( charIDToTypeID( 'ebbl' ), charIDToTypeID( 'ebbl' ), newBevelEmboss );
              newLayerEffects = localizeDescriptor( newLayerEffects );
              layerDesc = new ActionDescriptor();
              layerDesc.putObject( charIDToTypeID('Lefx'), charIDToTypeID('lfxv'), newLayerEffects);
              targetDesc = new ActionReference();
              targetDesc.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
              setDesc = new ActionDescriptor;
              setDesc.putObject( charIDToTypeID('T   '), charIDToTypeID('Lyr '), layerDesc );
              setDesc.putReference( charIDToTypeID('null' ), targetDesc );
              executeAction(charIDToTypeID('setd'), setDesc, DialogModes.NO);
          };
          
          var myHighlight Color = app.foregroundColor;// could be any Solid Color object
          setBevelEmbossHighlightColor( myHighlight Color );
          
          • 2. Re: How do I control a layer's Bevel and Emboss effect's "highlight color" through a script?
            WebNola Level 1

            I was able to figure it out before you replied by using adobe's scriptlistener plugin. The scriptlistener code may make no sense to me whatsoever, but it works. I want to thank you for your time, as I spent many hours searching for what you provided and couldn't find anything like it.

            • 3. Re: How do I control a layer's Bevel and Emboss effect's "highlight color" through a script?
              Michael L Hale Level 5

              No problem and I am glad you got it working using the scriptlistener log.

               

              One thing to note is that you can't modify just one setting of a layer effect using code from the log. Scriptlistener code is great if you want to set all the options of a layer style. But if you don't know what all the settings are or wheither there are other effects in addition to the one you want to edit log code will reset everything to whatever was used when is was recorded.