16 Replies Latest reply on Apr 27, 2011 8:58 AM by JJMack

    Marquee tool - size converted to text layer?

    Mal_Reed Level 1

      Firstly forgive me if this has been covered, the forum search just didn't work, even when searching for a something I could see!

       

      I'm wondering if there is a script that would do the following.

       

      With a rectangular marquee selection

      • create a new layer
      • stroke the marquee (1 pixel width)
      • (then add text, positioned outside the marquee at the top right hand side - in a small font size - to list the width and height)
      • w: <x>
      • h: <x>

       

      The purpose is to create a visual reference image for various 2D layout tasks.

       

      Cheers,
      Mal

        • 1. Re: Marquee tool - size converted to text layer?
          c.pfaffenbichler Level 9

          You could give this a try:

           

          // add layer with stroke and text with measurements of selection;
          // 2011, use it at your own risk;
          #target photoshop
          try {
               var state = app.activeDocument.activeHistoryState;
               app.activeDocument.selection.deselect();
               if (app.activeDocument.activeHistoryState != state) {
                    app.activeDocument.activeHistoryState = state
                    var check = true;
                    }
               else {
                    var check = false
                    };
               }
          catch (e) {var check = false};
          // if document and selection;
          if (check == true) {
               var originalRulerUnits = preferences.rulerUnits;
               preferences.rulerUnits = Units.PIXELS;
               var originalResolution = app.activeDocument.resolution;
               var myDocument = app.activeDocument;
               myDocument.resizeImage (undefined, undefined, 72, ResampleMethod.NONE);
          // get selection measurements;
               var theBounds = myDocument.selection.bounds;
               var width = theBounds[2] - theBounds[0];
               var height = theBounds[3] - theBounds[1];
          // make layer;
               var theLayer = makeFillLayer(width+"x"+height, 0, 0, 0, 0);
               theLayer.fillOpacity = 0;
               addStroke();
          // create a text layer;
               var textLayer = myDocument.artLayers.add();
               textLayer.kind = LayerKind.TEXT;
               textLayer.name = width+" x "+height;
               var myTextRef = textLayer.textItem;
               myTextRef.size = 12 * originalResolution / 72;
               myTextRef.font = "Arial-BoldMT";
          //Set text colour in RGB values
               var newColor = new SolidColor();
               newColor.rgb.red = 0;
               newColor.rgb.green = 0;
               newColor.rgb.blue = 0;
               myTextRef.color = newColor;
               myTextRef.justification = Justification.RIGHT;
               myTextRef.kind = TextType.POINTTEXT;     
               myTextRef.position = [theBounds[2], theBounds[1] - 10];
               myTextRef.contents = width+" x "+height;
               textLayer.blendMode = BlendMode.NORMAL;
               textLayer.opacity = 100;
          // reset;
               preferences.rulerUnits = originalRulerUnits;
               myDocument.resizeImage (undefined, undefined, originalResolution, ResampleMethod.NONE);
               };
          ////// the fill-layer-function //////
          function makeFillLayer (name, b, c, d, e) {
          var idMk = charIDToTypeID( "Mk  " );
              var desc6 = new ActionDescriptor();
              var idnull = charIDToTypeID( "null" );
                  var ref2 = new ActionReference();
                  var idcontentLayer = stringIDToTypeID( "contentLayer" );
                  ref2.putClass( idcontentLayer );
              desc6.putReference( idnull, ref2 );
              var idUsng = charIDToTypeID( "Usng" );
                  var desc7 = new ActionDescriptor();
                  var idNm = charIDToTypeID( "Nm  " );
                  desc7.putString( idNm, name );
                  var idType = charIDToTypeID( "Type" );
                      var desc8 = new ActionDescriptor();
                      var idClr = charIDToTypeID( "Clr " );
                          var desc9 = new ActionDescriptor();
                          var idCyn = charIDToTypeID( "Cyn " );
                          desc9.putDouble( idCyn, b );
                          var idMgnt = charIDToTypeID( "Mgnt" );
                          desc9.putDouble( idMgnt, c );
                          var idYlw = charIDToTypeID( "Ylw " );
                          desc9.putDouble( idYlw, d );
                          var idBlck = charIDToTypeID( "Blck" );
                          desc9.putDouble( idBlck, e );
                      var idCMYC = charIDToTypeID( "CMYC" );
                      desc8.putObject( idClr, idCMYC, desc9 );
                  var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );
                  desc7.putObject( idType, idsolidColorLayer, desc8 );
              var idcontentLayer = stringIDToTypeID( "contentLayer" );
              desc6.putObject( idUsng, idcontentLayer, desc7 );
          executeAction( idMk, desc6, DialogModes.NO );
          return app.activeDocument.activeLayer
          };
          ////// stroke //////
          function addStroke () {
          // =======================================================
          var idsetd = charIDToTypeID( "setd" );
              var desc5 = new ActionDescriptor();
              var idnull = charIDToTypeID( "null" );
                  var ref2 = new ActionReference();
                  var idPrpr = charIDToTypeID( "Prpr" );
                  var idLefx = charIDToTypeID( "Lefx" );
                  ref2.putProperty( idPrpr, idLefx );
                  var idLyr = charIDToTypeID( "Lyr " );
                  var idOrdn = charIDToTypeID( "Ordn" );
                  var idTrgt = charIDToTypeID( "Trgt" );
                  ref2.putEnumerated( idLyr, idOrdn, idTrgt );
              desc5.putReference( idnull, ref2 );
              var idT = charIDToTypeID( "T   " );
                  var desc6 = new ActionDescriptor();
                  var idScl = charIDToTypeID( "Scl " );
                  var idPrc = charIDToTypeID( "#Prc" );
                  desc6.putUnitDouble( idScl, idPrc, 416.666667 );
                  var idFrFX = charIDToTypeID( "FrFX" );
                      var desc7 = new ActionDescriptor();
                      var idenab = charIDToTypeID( "enab" );
                      desc7.putBoolean( idenab, true );
                      var idStyl = charIDToTypeID( "Styl" );
                      var idFStl = charIDToTypeID( "FStl" );
                      var idInsF = charIDToTypeID( "InsF" );
                      desc7.putEnumerated( idStyl, idFStl, idInsF );
                      var idPntT = charIDToTypeID( "PntT" );
                      var idFrFl = charIDToTypeID( "FrFl" );
                      var idSClr = charIDToTypeID( "SClr" );
                      desc7.putEnumerated( idPntT, idFrFl, idSClr );
                      var idMd = charIDToTypeID( "Md  " );
                      var idBlnM = charIDToTypeID( "BlnM" );
                      var idNrml = charIDToTypeID( "Nrml" );
                      desc7.putEnumerated( idMd, idBlnM, idNrml );
                      var idOpct = charIDToTypeID( "Opct" );
                      var idPrc = charIDToTypeID( "#Prc" );
                      desc7.putUnitDouble( idOpct, idPrc, 100.000000 );
                      var idSz = charIDToTypeID( "Sz  " );
                      var idPxl = charIDToTypeID( "#Pxl" );
                      desc7.putUnitDouble( idSz, idPxl, 1.000000 );
                      var idClr = charIDToTypeID( "Clr " );
                          var desc8 = new ActionDescriptor();
                          var idRd = charIDToTypeID( "Rd  " );
                          desc8.putDouble( idRd, 0.000000 );
                          var idGrn = charIDToTypeID( "Grn " );
                          desc8.putDouble( idGrn, 0.000000 );
                          var idBl = charIDToTypeID( "Bl  " );
                          desc8.putDouble( idBl, 0.000000 );
                      var idRGBC = charIDToTypeID( "RGBC" );
                      desc7.putObject( idClr, idRGBC, desc8 );
                  var idFrFX = charIDToTypeID( "FrFX" );
                  desc6.putObject( idFrFX, idFrFX, desc7 );
              var idLefx = charIDToTypeID( "Lefx" );
              desc5.putObject( idT, idLefx, desc6 );
          executeAction( idsetd, desc5, DialogModes.NO );
          };
          

          1 person found this helpful
          • 2. Re: Marquee tool - size converted to text layer?
            Michael L Hale Level 5

            c.pfaffenbichler beat me to this but I was thinking more along the lines of the code below. It expects a selection and uses the foreground color.

            var originalRulerUnits = app.preferences.rulerUnits;
            app.preferences.rulerUnits = Units.PIXELS;
            var selectionBounds = app.activeDocument.selection.bounds;
            var selectionWidth = selectionBounds[2]-selectionBounds[0];
            var selectionHeight = selectionBounds[3]-selectionBounds[1];
            app.activeDocument.artLayers.add();
            app.activeDocument.selection.stroke (app.foregroundColor, 1, StrokeLocation.OUTSIDE);
            app.activeDocument.selection.deselect();
            var textLayer = app.activeDocument.artLayers.add();
            textLayer.kind = LayerKind.TEXT;
            textLayer.textItem.position = [selectionBounds[0]+5,selectionBounds[1]-5];
            textLayer.textItem.color = app.foregroundColor;
            textLayer.textItem.font = "ComicSansMS";
            textLayer.textItem.size = 12;
            textLayer.textItem.contents = ('W:'+selectionWidth+' H:'+selectionHeight);
            executeAction( charIDToTypeID('Mrg2'), undefined, DialogModes.NO );
            app.preferences.rulerUnits = originalRulerUnits;
            
            • 3. Re: Marquee tool - size converted to text layer?
              c.pfaffenbichler Level 9

              Conciseness being advantageous when it comes to Scripting your Scripts seems much preferable.

               

              Have a good weekend

              Pfaffenbichler

              • 4. Re: Marquee tool - size converted to text layer?
                Mal_Reed Level 1

                Hi guys, thank you so much for going to the effort of actually making these scripts.

                 

                I'm new to scripting to Photoshop (done some js in 3d apps) so I need to get practicing here -  I'll look for some starter tutorials.

                 

                Pfaffenbichier, I got an error testing yours...

                 

                "The command “<unknown>” is not currently available.

                Line: 85

                ->  executeAction( idMk, desc6, DialogModes.NO );"

                 

                Thanks for the input here guys.

                • 5. Re: Marquee tool - size converted to text layer?
                  c.pfaffenbichler Level 9

                  What color mode is the image?

                  It should work for any layer-capable mode (in CS5).

                   

                  I'm new to scripting to Photoshop (done some js in 3d apps) so I need to get practicing here -  I'll look for some starter tutorials.

                  You could check out »Photoshop CS5 Scripting Guide.pdf« and »Photoshop CS5 JavaScript Ref.pdf«.

                  Can’t remember if they are part of the installation but you should be able to find them on the net at least.

                  • 6. Re: Marquee tool - size converted to text layer?
                    Michael L Hale Level 5

                    c.pfaffenbichler, I tested you code and it works for me without errors. It also results in a smaller file size than my version. If there are a lot of selected areas to mark you code would produce a much smaller file.

                    • 7. Re: Marquee tool - size converted to text layer?
                      c.pfaffenbichler Level 9

                      Thanks for testing.

                      And the result surprises me – the Script uses the Style Stroke on a Solid Color Layer, but I’m not quite sure why that would produce a smaller file.

                      • 8. Re: Marquee tool - size converted to text layer?
                        Michael L Hale Level 5

                        It surprises me too. It looks like a fill layer with an effect and mask plus a text layer takes up less room than an artLayer even if most of that artLayer is transparent.

                        • 9. Re: Marquee tool - size converted to text layer?
                          c.pfaffenbichler Level 9

                          Seems to only apply for files saved without »Maximize PSD and PSB File Compatibility«; when saved with maximized compatibility your Script seems to produce smaller files.

                          • 10. Re: Marquee tool - size converted to text layer?
                            Mal_Reed Level 1

                            Hi c.pfaffenbichier and Michael

                             

                            Thanks for the heads up in getting started with scripting in photoshop, I'm now using the ExtendedScript toolkit and the listener plug-in. I'm still completely fumbling around in the dark, but looking forward to learning more.

                             

                            Standing on the shoulders of giants I've updated the script to be more universal, so it will now test the selection width and height. Them either print the dimensions for both, or just the appropriate one. It's now working well for my needs.

                             

                            //get the units used from the prefs
                            var originalRulerUnits = app.preferences.rulerUnits;
                            //set units to pixels
                            app.preferences.rulerUnits = Units.PIXELS;
                            //get parameters of selection bounds
                            var selectionBounds = app.activeDocument.selection.bounds;
                            var selectionWidth = selectionBounds[2]-selectionBounds[0];
                            var selectionHeight = selectionBounds[3]-selectionBounds[1];
                            //add layer
                            app.activeDocument.artLayers.add();
                            //stroke selection
                            app.activeDocument.selection.stroke (app.foregroundColor, 1, StrokeLocation.INSIDE);
                            app.activeDocument.selection.deselect();
                            //create text layer
                            var textLayer = app.activeDocument.artLayers.add();
                            textLayer.kind = LayerKind.TEXT;
                            textLayer.textItem.color = app.foregroundColor;
                            textLayer.textItem.font = "Ariel";
                            textLayer.textItem.size = 12;
                            
                            if (selectionWidth >1 && selectionHeight >1)
                                {
                                    textLayer.textItem.position = [selectionBounds[0]+((selectionWidth/2)-15),selectionBounds[1]-5];
                                    textLayer.textItem.contents = ('w. '+selectionWidth);//+'\r'+'h. '+selectionHeight);
                                    executeAction( charIDToTypeID('Mrg2'), undefined, DialogModes.NO );
                                    
                                    var textLayer = app.activeDocument.artLayers.add();
                                    textLayer.kind = LayerKind.TEXT;
                                    textLayer.textItem.position = [selectionBounds[2]+5,selectionBounds[1]+((selectionHeight/2)-0)];
                                    textLayer.textItem.contents = ('h. '+selectionHeight);//+'\r'+'h. '+selectionHeight);
                                    executeAction( charIDToTypeID('Mrg2'), undefined, DialogModes.NO );
                                }
                            else
                                {
                                if ( selectionWidth>2)
                                    {
                                    textLayer.textItem.position = [selectionBounds[0]+((selectionWidth/2)-15),selectionBounds[1]-5];
                                    textLayer.textItem.contents = ('w. '+selectionWidth);//+'\r'+'h. '+selectionHeight);
                                    executeAction( charIDToTypeID('Mrg2'), undefined, DialogModes.NO );
                                    }
                                else
                                    {
                                    textLayer.textItem.position = [selectionBounds[2]+5,selectionBounds[1]+((selectionHeight/2)-0)];
                                    textLayer.textItem.contents = ('h. '+selectionHeight);//+'\r'+'h. '+selectionHeight);
                                    executeAction( charIDToTypeID('Mrg2'), undefined, DialogModes.NO );
                                    }
                                }
                            //set ruler units back to what they were.
                            app.preferences.rulerUnits = originalRulerUnits;
                            

                             

                            I'm certain there would be cleaner ways to produce this. And possibly make it into it's own tool so the width and height are drawn automatically?

                             

                            Anyway thanks for your input.

                            Cheers,

                            Mal

                            • 11. Re: Marquee tool - size converted to text layer?
                              JJMack Most Valuable Participant

                              Your script will not work for selection that are at the top edge or at the right side because of where it place the text the text would fall off canvas. Also older versions of Photosgop like CS2 will fail because selectoin bounds does not work there.

                              • 12. Re: Marquee tool - size converted to text layer?
                                Mal_Reed Level 1

                                Hi JJMack,

                                 

                                I'm aware of the text positioning issues, its a personal tool that works for me at the moment with the layout docs I'm producing. Any suggestion of how you might solve that issue, might help another reader? There are some other situations in which it won't work, if you add to a selection to create multiple rects for example.

                                 

                                I'm not aware of any version limitations being new to PS scripting. Certainly something you need to think about if you intend to distribute a tool.

                                 

                                Cheers,

                                Mal

                                • 13. Re: Marquee tool - size converted to text layer?
                                  JJMack Most Valuable Participant

                                  Selections do not need to be rectangular and there can be wholes and separate areas. However there is only a single rectangular selection bounds that would encompass every selected area. Here is an example I used the custom shape tool to drag out a Path. I converted the path to a selection and ran your script this is what was produced. sls.jpg

                                  • 14. Re: Marquee tool - size converted to text layer?
                                    Mal_Reed Level 1

                                    Yeah I know how it works

                                     

                                    I was simply making the point that if you make 2 rect selections, the tool doesn't give you the dimensions of both rects, just the bounding volume of the combined selection area as you have demonstrated for us. Perhaps I could of explained that better first time!

                                     

                                    Cheers,

                                    Mal

                                    • 15. Re: Marquee tool - size converted to text layer?
                                      Michael L Hale Level 5

                                      JJMack wrote:

                                       

                                      Selections do not need to be rectangular and there can be wholes and separate areas.

                                      If you read the first post in this thread you will see that this was not meant to work with any selection.

                                      • 16. Re: Marquee tool - size converted to text layer?
                                        JJMack Most Valuable Participant

                                        Michael I did read that and the appends that followed including the script he modified and posted in this thread  change happens as you know. Clearly the script handles selection thicker then one pixel and will work on any selection and only run into problems with text falling off canvas