18 Replies Latest reply on Aug 28, 2011 11:47 AM by JJMack

    Script Request??

    jmarkt Level 1

      Wondering if anyone was willing to take the time to write a script for PS CS5 on an iMAC that would allow me to resize the contents of specific folders, by name?  The attached folder hierarchy is representative of two (10-271 and 10-272) of over 100 folders within the root directory of CustomHeadwear.  Each of the 100+ folders has identical four sub-folders, i.e. Additional, Back, Front and Small.

       

      hierarchy.jpg

       


      I really need a script that would allow me to resize each of the sub-folders to specific individual width and lengths, based upon name.  For example, if the script could provide an initial interface, similar to below, that would allow me to type in as many as four folder names, and then specific width, height or percentage increase/decrease for each of these folders.  I suppose there would also have to be a Name box for the Root Folder?

       

      scriptInterface.jpg

       

       

       


      I simply don’t have the expertise to create scripts, but I’ve certainly benefited from the expertise of those who have contributed to this Forum!  Thanks for any help!!

        • 1. Re: Script Request??
          JJMack Most Valuable Participant

          The script you requestion would need to be fully designed the outline you described I'm sure does not include all the details involved.  It would be a complex program to design and program not a quick hack. For example width height  is that a force fit distort or a fit image constrained type resize.

           

          Look at Russell Browns web site for the Image Process Pro script it is a Photoshop Plug-in script you can record it in actions and it will run without a Dialog when the action is played if you keep re-using the input folders.  If the folders names change you can use the Image Process Pro dialog.  The Image Processor Pro is found from menu File>Automate>Image Processor Pro.  This Image Processor besides being a Plug-in script has a Tabed middle section where you can add and remove desired output file type with different resize settings.  Tabs images can be turn on and off.  You can also save the setup you make to this tabed section.  These save setup can also be loaded.  So you could create a library of the setup you needs and just load the setup you need for your different tree types.

          • 2. Re: Script Request??
            jmarkt Level 1

            Thanks, JJMack, for the heads up.  I've installed the script and viewed the tutorial, and I think it will work for my project.  The only thing I'm not sure about yet is whether IPP will, after resizing images in the first named sub-folder, then continue on to the next folder, locating similarly named sub-folders and resizing them as well??  Whatever the result, this will be a beneficial tool to have - thanks again!

            ===============

            • 3. Re: Script Request??
              c.pfaffenbichler Level 9
              that would allow me to type in as many as four folder names,

              Quite frankly that seems odd (and in case of typing-errors problematic).

              Is there a reason you don’t want to use a Folder-dialog?

              • 4. Re: Script Request??
                jmarkt Level 1

                Thanks for the reply.  I guess I don't know what you mean by "Folder-dialog"??  The issue is, I have 112 folders, and each has four identically named sub-folders.  All four of these sub-folders need to be resized, i.e. XXXX1 may contain 25 PNG images that need to be one consistent size; XXXX2 may contain 30 PNG images that need to be another consistent size; XXXX3 may contain 10 PNG images that need to be yet another size, etc., then on to the next folder.  I only used the number "four" because that is the number of sub-folders in each of the 112 folders.  These 112 folders only cover one root folder - there are eleven more root folders, containing approximately 8,000 images, awaiting the same application.

                 

                Perhaps I'm not using the correct verbiage, but the above is what I need to do.   If a "Folder-dialog" would accomplish this, without doing a "folder by folder" resizing, that would be great!  Thanks again.

                =============

                • 5. Re: Script Request??
                  JJMack Most Valuable Participant

                  As I wrote the script you requested could be written. You would need to design the whole process and create a dialog that would suite the process.  The dialog you showed would require you to enter or select the full path for each folder.  You would more likely want instead a filed for the root folder so all you need to do then idenitfy the sub folders and their resize options..  Its not a hard process it just process each sub folder files through a FitImage function with passed vars.

                  You don't know scripting so your not up to that task.  That is why I suggested an Image Processor type solution for you. You can set it dialog to select a folder and set in its output file section where you want to place resize image in some image file format. Only one folder at a time if the sizes are different if the same you can precess the whole tree.  You need write nothing only learn a dialog. Not learn a scripting language like javescript and Adobe Photoshop  Document Object Model find out you can not do some things Learn about the ScriptListener and the Action Manager interface to do thing not posible with Adobe's DOM.

                   

                  A folder dialog is a normal Open type windows type dialog where you can transverse a file system tree and select the folder or file you wish to precess.

                  • 6. Re: Script Request??
                    jmarkt Level 1

                    Hi JJMack - Thanks for all the input; however, looking at the folder hierarchy I included in my initial post, these are just two of 112 folders.  The "root" folder being CustomHeadwear, parent folders 10-271 and 10-272, each having a sub-folder called "Additional".  It's not clear to me how Image Processor Pro can systematically resize 112 sub-folders named "Additional", without having to do the resizing one sub-folder at a time???

                     

                    If 112 folders were all I had to do, I would simply trudge through; however, as I've posted, I have a total of approximately 8,000 images in some 800 folders that need to be resized, by sub-folder names.

                    • 7. Re: Script Request??
                      JJMack Most Valuable Participant

                      I feel if you want that custom script you should bite the bullet design it fully and try code it. If you run into problems I'm sure users here will bend over backwards to help you with your problems.  However using this forum as coder substitute IMO is not proper use of this resourse.

                      • 8. Re: Script Request??
                        jmarkt Level 1

                        Sorry.

                        • 9. Re: Script Request??
                          Michael L Hale Level 5

                          No need to feel sorry, people ask for help with script all the time. Because your workflow is not commom I do not think that you will find an already written script.

                           

                          Below is a rough start. All it does now is display an ugly dialog to see if I understand what you want. If this is close I can help with the rest.

                           

                          // get the root folder from the user
                          var rootFolder = Folder.selectDialog('Please select the root folder');
                          if( rootFolder != null ){// if the user did not cancel the dialog
                               // get all the product folders in rootFolder
                               var productFolders = rootFolder.getFiles(isFolder);
                               // get all the subFolders in the first product folder
                               var subFolders = productFolders[0].getFiles(isFolder);
                               // now that we have the needed info create and show the dialog
                               var win = createDialog();
                               initializeDialog(win);
                               var res = runDialog(win);
                               if( res == 1){
                                    // process the files
                               }
                          }
                               
                          function createDialog( ) {
                             var dlg = new Window( 'dialog', 'Your script name here' );
                             dlg.alignChildren = 'left';
                             dlg.RootPnl = dlg.add( 'panel', undefined, 'Root Folder' );
                             dlg.RootPnl.stPath = dlg.RootPnl.add('statictext', undefined, decodeURI(rootFolder));
                             dlg.RootPnl.stPath.preferredSize.width = 300;
                             dlg.subPnl = dlg.add('panel',undefined,'SubFolders');
                             dlg.subPnl.alignChildren = 'right';
                             dlg.subPnl.stHeader = dlg.subPnl.add('statictext',undefined,'folder             width              height');
                               dlg.subPnl.grp1 = dlg.subPnl.add('group');
                               dlg.subPnl.grp1.stFolder = dlg.subPnl.grp1.add('statictext',undefined,subFolders[0].name);
                               dlg.subPnl.grp1.etWidth = dlg.subPnl.grp1.add('edittext');
                               dlg.subPnl.grp1.etWidth.preferredSize.width = 40;
                               dlg.subPnl.grp1.spacer = dlg.subPnl.grp1.add('statictext');
                               dlg.subPnl.grp1.spacer.preferredSize.width = 10;
                               dlg.subPnl.grp1.etHeight = dlg.subPnl.grp1.add('edittext');
                               dlg.subPnl.grp1.etHeight.preferredSize.width = 40;
                               
                                    dlg.subPnl.grp2 = dlg.subPnl.add('group');
                               dlg.subPnl.grp2.stFolder = dlg.subPnl.grp2.add('statictext',undefined,subFolders[1].name);
                               dlg.subPnl.grp2.etWidth = dlg.subPnl.grp2.add('edittext');
                               dlg.subPnl.grp2.etWidth.preferredSize.width = 40;
                               dlg.subPnl.grp2.spacer = dlg.subPnl.grp2.add('statictext');
                               dlg.subPnl.grp2.spacer.preferredSize.width = 10;
                               dlg.subPnl.grp2.etHeight = dlg.subPnl.grp2.add('edittext');
                               dlg.subPnl.grp2.etHeight.preferredSize.width = 40;
                               
                                    dlg.subPnl.grp3 = dlg.subPnl.add('group');
                               dlg.subPnl.grp3.stFolder = dlg.subPnl.grp3.add('statictext',undefined,subFolders[2].name);
                               dlg.subPnl.grp3.etWidth = dlg.subPnl.grp3.add('edittext');
                               dlg.subPnl.grp3.etWidth.preferredSize.width = 40;
                               dlg.subPnl.grp3.spacer = dlg.subPnl.grp3.add('statictext');
                               dlg.subPnl.grp3.spacer.preferredSize.width = 10;
                               dlg.subPnl.grp3.etHeight = dlg.subPnl.grp3.add('edittext');
                               dlg.subPnl.grp3.etHeight.preferredSize.width = 40;
                               
                                    dlg.subPnl.grp4 = dlg.subPnl.add('group');
                               dlg.subPnl.grp4.stFolder = dlg.subPnl.grp4.add('statictext',undefined,subFolders[3].name);
                               dlg.subPnl.grp4.etWidth = dlg.subPnl.grp4.add('edittext');
                               dlg.subPnl.grp4.etWidth.preferredSize.width = 40;
                               dlg.subPnl.grp4.spacer = dlg.subPnl.grp4.add('statictext');
                               dlg.subPnl.grp4.spacer.preferredSize.width = 10;
                               dlg.subPnl.grp4.etHeight = dlg.subPnl.grp4.add('edittext');
                               dlg.subPnl.grp4.etHeight.preferredSize.width = 40;
                               
                                  
                             dlg.btnPnl = dlg.add( 'panel');
                             dlg.btnPnl.orientation = "row";
                             dlg.btnPnl.alignment = "right";
                             dlg.btnPnl.preferredSize [ 80, 80 ]
                             dlg.btnPnl.okBtn = dlg.btnPnl.add( 'button', undefined, 'Ok', { name:'ok' });
                             dlg.btnPnl.cancelBtn = dlg.btnPnl.add( 'button', undefined, 'Cancel', { name:'cancel' });
                             return dlg;
                          };
                          function initializeDialog( w ) {
                          
                          };
                          function runDialog( w ) {
                             return w.show( );
                          };
                          function isFolder(f) {
                              return f instanceof Folder;
                          }
                          
                          
                          • 10. Re: Script Request??
                            JJMack Most Valuable Participant

                            See users want to help. Just sane Michael code int a file like MeRequestedScrip.jsx on you desktop and drag and drop it on Photoshop and point it to \CustomHeadware

                             

                            Michael I get a undefined error with the script If I go one level down which I think is what he wants but you might be right and he want all filders under a product like customheadware. For he stated they all have the same subfolder structure but I think that the script would need to verify that to be true...

                             

                            Think he needs to spec out the design better.

                            UndefineedError.jpg

                            Produucts.jpg

                            • 11. Re: Script Request??
                              Michael L Hale Level 5

                              The script was set up to work with his folder structure with CustomHeadware being the root folder. I would expect errors if the structure is different.Because the script is written to work with a specific workflow I don't think it is necessary to verify the folder structure. Any errors at this point would mean that the folder structure doen't match and the script should stop.

                               

                              It sounded to me like he wanted to process the all of the product folders in CustomHeadware in one pass.

                              • 12. Re: Script Request??
                                jmarkt Level 1

                                Thanks, Mike.  The dialog box is exactly what I had in mind!  If I could enter the new dimensions for each of these four named sub-folders and have the script resize/replace all images within the 112 sub-folders named "Additional"; all 112 sub-folders named "Small", et al, would be perfect!

                                 

                                As JJMack indicated, I know this is not a "quick hack" and takes a lot of time.  I really appreciate your help, Mike.  I presume you're the same Mike Hale that was so helpful back in my "Pinnacle" days??  Anyway, thanks again!

                                ==============

                                • 13. Re: Script Request??
                                  Michael L Hale Level 5

                                  jmarkt wrote:

                                   

                                  I presume you're the same Mike Hale that was so helpful back in my "Pinnacle" days??

                                  I go by Mike Hale over at PS-Scripts.com but I'm afraid that "Pinnacle days" is not enough for me to remember if I was the one that was helpful then.

                                   

                                  At any rate, I guess I now need to know what format(s) the files are now and how you want them saved. Do you want to overwrite the existing files? Save in a different location or with a different name, that kind of thing.

                                  • 14. Re: Script Request??
                                    jmarkt Level 1

                                    Mike - All files are PNG format, and overwriting/saving as PNG is great.  Saving them in the same folders is perfect.

                                     

                                    Just to make sure I've been clear, the Root folder is Custom Planet, as you have stated.  The script will subsequently be applied to CustomHeadwear/10-271/Additional, Front, Back, Small; then 10-272/Additional, Front, Back, Small, et al.  I then will use the script on Custom Planet/CustomClothing/363M/Additional, Front, Back, Small, etc. through approximately 60 folders, etc.  There are 11 other products, each with about 50 folders.  Every product has four folders (Additional, Front, Back and Small).  Custom Planet will be the root folder in all cases, then the product description folder (CustomHeadwear, CustomClothing, etc), then the product ID (10-271, 363M, 715, etc.).

                                     

                                    BTW, Pinnacle was referring to the video editing software I used back in 2002, and a Mike Hale was a very helpful expert for many people in their Forum at that time.

                                     

                                    Thanks again for your time, Mike!

                                    ==============

                                    • 15. Re: Script Request??
                                      Michael L Hale Level 5

                                      Ok, here is a quick and dirty script that should be close to what you want. The dialog is still ugly and there is limited error checking. Because it overwrites the files I suggest that you do a small test or at least backup you files before you run the script on important files. I did test it using WinXP and CS5 on a small test set and it seems to be working fine. But again use at your own risk.

                                       

                                      // get the root folder from the user
                                      var rootFolder = Folder.selectDialog('Please select the root folder');
                                      if( rootFolder != null ){// if the user did not cancel the dialog
                                           // get all the product folders in rootFolder
                                           var productFolders = rootFolder.getFiles(isFolder);
                                           // get all the subFolders in the first product folder
                                           var subFolders = productFolders[0].getFiles(isFolder);
                                           // now that we have the needed info create and show the dialog
                                           var win = createDialog();
                                           initializeDialog(win);
                                           var res = runDialog(win);
                                           if( res == 1){
                                                // process the files
                                                for( var p = 0;p<productFolders.length;p++){
                                                     var folders = productFolders[p].getFiles(isFolder);
                                                     for( var f = 0; f<folders.length;f++){
                                                          var folderName = folders[f].name.toLocaleLowerCase();
                                                          switch( folderName ){
                                                               case subFolders[0].name.toLocaleLowerCase():
                                                                    processFolder( folders[f], Number(win.etWidth1.text), Number(win.etHeight1.text));
                                                                    break;
                                                               case subFolders[1].name.toLocaleLowerCase():
                                                                    processFolder( folders[f], Number(win.etWidth2.text), Number(win.etHeight2.text));
                                                                    break;
                                                               case subFolders[2].name.toLocaleLowerCase():
                                                                    processFolder( folders[f], Number(win.etWidth3.text), Number(win.etHeight3.text));
                                                                    break;
                                                               case subFolders[3].name.toLocaleLowerCase():
                                                                    processFolder( folders[f], Number(win.etWidth4.text), Number(win.etHeight4.text));
                                                                    break;
                                                               default: break;
                                                          }
                                                     }
                                                }
                                           }
                                      }
                                      
                                      function processFolder( folder, w, h ){
                                          var files = folder.getFiles(/png$/i);
                                           for(var f = 0; f<files.length;f++){
                                                app.open(files[f]);
                                                fitImage(w,h);
                                                app.activeDocument.close(SaveOptions.SAVECHANGES);
                                           }
                                      };
                                      function createDialog( ) {
                                         var dlg = new Window( 'dialog', 'Your script name here' );
                                         dlg.alignChildren = 'left';
                                         dlg.RootPnl = dlg.add( 'panel', undefined, 'Root Folder' );
                                         dlg.RootPnl.stPath = dlg.RootPnl.add('statictext', undefined, decodeURI(rootFolder));
                                         dlg.RootPnl.stPath.preferredSize.width = 300;
                                         dlg.subPnl = dlg.add('panel',undefined,'SubFolders');
                                         dlg.subPnl.alignChildren = 'right';
                                         dlg.subPnl.stHeader = dlg.subPnl.add('statictext',undefined,'folder             width(px)      height(px)');
                                           dlg.subPnl.grp1 = dlg.subPnl.add('group');
                                           dlg.subPnl.grp1.stFolder = dlg.subPnl.grp1.add('statictext',undefined,subFolders[0].name);
                                           dlg.etWidth1 = dlg.subPnl.grp1.add('edittext');
                                            dlg.etWidth1.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etWidth1.preferredSize.width = 40;
                                           dlg.subPnl.grp1.spacer = dlg.subPnl.grp1.add('statictext');
                                           dlg.subPnl.grp1.spacer.preferredSize.width = 10;
                                           dlg.etHeight1 = dlg.subPnl.grp1.add('edittext');
                                            dlg.etHeight1.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etHeight1.preferredSize.width = 40;
                                           
                                           dlg.subPnl.grp2 = dlg.subPnl.add('group');
                                           dlg.subPnl.grp2.stFolder = dlg.subPnl.grp2.add('statictext',undefined,subFolders[1].name);
                                           dlg.etWidth2 = dlg.subPnl.grp2.add('edittext');
                                            dlg.etWidth2.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etWidth2.preferredSize.width = 40;
                                           dlg.subPnl.grp2.spacer = dlg.subPnl.grp2.add('statictext');
                                           dlg.subPnl.grp2.spacer.preferredSize.width = 10;
                                           dlg.etHeight2 = dlg.subPnl.grp2.add('edittext');
                                            dlg.etHeight2.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etHeight2.preferredSize.width = 40;
                                           
                                           dlg.subPnl.grp3 = dlg.subPnl.add('group');
                                           dlg.subPnl.grp3.stFolder = dlg.subPnl.grp3.add('statictext',undefined,subFolders[2].name);
                                           dlg.etWidth3 = dlg.subPnl.grp3.add('edittext');
                                            dlg.etWidth3.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etWidth3.preferredSize.width = 40;
                                           dlg.subPnl.grp3.spacer = dlg.subPnl.grp3.add('statictext');
                                           dlg.subPnl.grp3.spacer.preferredSize.width = 10;
                                           dlg.etHeight3 = dlg.subPnl.grp3.add('edittext');
                                            dlg.etHeight3.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etHeight3.preferredSize.width = 40;
                                           
                                            dlg.subPnl.grp4 = dlg.subPnl.add('group');
                                           dlg.subPnl.grp4.stFolder = dlg.subPnl.grp4.add('statictext',undefined,subFolders[3].name);
                                           dlg.etWidth4 = dlg.subPnl.grp4.add('edittext');
                                            dlg.etWidth4.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etWidth4.preferredSize.width = 40;
                                           dlg.subPnl.grp4.spacer = dlg.subPnl.grp4.add('statictext');
                                           dlg.subPnl.grp4.spacer.preferredSize.width = 10;
                                           dlg.etHeight4 = dlg.subPnl.grp4.add('edittext');
                                            dlg.etHeight4.addEventListener ('keydown', NumericEditKeyboardHandler );
                                           dlg.etHeight4.preferredSize.width = 40;
                                           
                                              
                                         dlg.btnPnl = dlg.add( 'panel');
                                         dlg.btnPnl.orientation = "row";
                                         dlg.btnPnl.alignment = "right";
                                         dlg.btnPnl.preferredSize [ 80, 80 ]
                                         dlg.btnPnl.okBtn = dlg.btnPnl.add( 'button', undefined, 'Ok', { name:'ok' });
                                         dlg.btnPnl.cancelBtn = dlg.btnPnl.add( 'button', undefined, 'Cancel', { name:'cancel' });
                                         return dlg;
                                      };
                                      function initializeDialog( w ) {
                                      
                                      };
                                      function runDialog( w ) {
                                         return w.show( );
                                      };
                                      function isFolder(f) {
                                          return f instanceof Folder;
                                      };
                                      function fitImage(w,h){
                                           var fitImage = stringIDToTypeID( "3caa3434-cb67-11d1-bc43-0060b0a13dc4" );
                                                var size = new ActionDescriptor();
                                                size.putUnitDouble( charIDToTypeID( "Wdth" ), charIDToTypeID( "#Pxl" ), w );
                                                size.putUnitDouble( charIDToTypeID( "Hght" ), charIDToTypeID( "#Pxl" ), h );
                                           executeAction( fitImage, size, DialogModes.NO );
                                      };
                                      ///////////////////////////////////////////////////////////////////////////////
                                      // Function: NumericEditKeyboardHandler
                                      // Usage: Do not allow anything except for numbers 0-9
                                      // Input: ScriptUI keydown event
                                      // Return: <nothing> key is rejected and beep is sounded if invalid
                                      // From the script 'Fit Image.jsx' by Adobe
                                      ///////////////////////////////////////////////////////////////////////////////
                                      function NumericEditKeyboardHandler (event) {
                                          try {
                                              var keyIsOK = KeyIsNumeric (event) || 
                                                              KeyIsDelete (event) || 
                                                                 KeyIsLRArrow (event) ||
                                                                 KeyIsTabEnterEscape (event);
                                                                 
                                              if (! keyIsOK) {
                                                  //    Bad input: tell ScriptUI not to accept the keydown event
                                                  event.preventDefault();
                                                  /*    Notify user of invalid input: make sure NOT
                                                      to put up an alert dialog or do anything which
                                                      requires user interaction, because that
                                                      interferes with preventing the 'default'
                                                      action for the keydown event */
                                                  app.beep();
                                              }
                                          }
                                          catch (e) {
                                              ; // alert ("Ack! bug in NumericEditKeyboardHandler: " + e);
                                          }
                                      };
                                      //    key identifier functions
                                      function KeyIsNumeric ( event ) {
                                          return  ( event.keyName >= '0' ) && ( event.keyName <= '9' ) && ! KeyHasModifier ( event );
                                      };
                                      function KeyHasModifier ( event ) {
                                          return event.shiftKey || event.ctrlKey || event.altKey || event.metaKey;
                                      };
                                      function KeyIsDelete (event) {
                                          //    Shift-delete is ok
                                          return (event.keyName == 'Backspace') && ! (event.ctrlKey);
                                      };
                                      function KeyIsLRArrow (event) {
                                          return ((event.keyName == 'Left') || (event.keyName == 'Right')) && ! (event.altKey || event.metaKey);
                                      };
                                      function KeyIsTabEnterEscape (event) {
                                           return event.keyName == 'Tab' || event.keyName == 'Enter' || event.keyName == 'Escape';
                                      };
                                      
                                      • 16. Re: Script Request??
                                        jmarkt Level 1

                                        Mike - It worked EXACTLY as intended!  Will save me much time and I thank you so much for doing this!

                                        +++++++++++++++

                                        • 17. Re: Script Request??
                                          JJMack Most Valuable Participant

                                          jmarkt a question I ask that you never answered. The Dialog you showed to begin with had Width Heignt or +-%.  I ask if the Width and Hight was to be a force fit distort to that absolute size or a constrained resize like FitImage.   Michael uses the FitImage Plug-in in his script  which will resize an image up or down in size and constrain the resize to matain the images current aspect ratio and not distort. Is this what you want?

                                          • 18. Re: Script Request??
                                            jmarkt Level 1

                                            The four sub-folders all contain identical images, but each folder has a different sized images.  Some (not many) of the images will have to be "force fit" or resized to specific dimensions.  The request for "+/-%" would have been a back up option to apply to those very few.  Mike's script was exactly what I needed and saved me so much time, and that I am glad to do a handful of them manually!