Skip to main content
sourabhverma
Known Participant
May 28, 2019
Question

Portraits Cropping Automation

  • May 28, 2019
  • 5 replies
  • 8127 views

Hello Everyone,

 

I need your help!

 

Actually, I have a bulk of portraits images. And I want to crop them all on the same position, same in size, head size, eye position so they all can seem consistent.  The required final dimension will be
8x10. I do not want to crop them manually. I need an automated process for the same. Can you please suggest to me so I can avoid manual work and save a lot of time.

 

Thank You in Advance

5 replies

c.pfaffenbichler
Community Expert
Community Expert
September 16, 2021

There also was a thread recently in which @jazz-y managed to use Liquify in a Script to locate faces with a Script. 

Crop/trim image automation 3:4

JJMack
Community Expert
Community Expert
September 27, 2021

Jazz-z posted a script not too long ago where he basically used  a liquify mesh he had  that he use with liquify  to select  the head in a portrait image.    You should be able to modify that script to be able to set a 4:5 aspect ration portrait selection. To crop your portrait images to approximately the same size 8" x 10"  Portrait where all heads will be about the same size and located in the same image area.  I would use the modified script in an action that would resize the 4:5 crop image to be 8" x 10" at the ppi you want.  The action could also be made interactive where  you could reposition the position of the Crop selection the modified script sets so you can tweak  portrait  selected before the action crop the image and resizes to 8" x 10".   

Something like:

 

 

You show all your original portraits are near the sane size and all seem to be shot by the sane camera and setup.  You would need to modify the script to sett and appropriate 4:5 selection for your original image.    I downloaded some random portrait from the web.  They all were croped 8"x10" however the portrait composition varies  because the camera set up and  portrait compositions varied greatly as did the image sizes.

JJMack
didiermazier
Community Expert
Community Expert
May 10, 2020

We recently exchanged on a similar thread regarding croping and resizing a bunch of images of various sizes and even resolution… Scripts could work but we found also some interesting native solutions. You should have look at this to get insights…Fashion e-commerce AutoSelect Subject and Crop

Chuck Uebele
Community Expert
Community Expert
May 28, 2019

I used to have a script that would place guides for sizing and cropping on portraits, as we had a lot of photos and need all our corporate headshots to be consistent. I'll have to see if I still have that script.

Chuck Uebele
Community Expert
Community Expert
May 28, 2019

I did find the script. It's customized for our standards, but you can get an idea. What it does is create a set of shape layers in which you size and position over a face. Then if you select "Add permanent guides, it creates cropping guides. If you leave that uncheck, it crops, but it will do it to our specs DPI, etc.

#target photoshop

var oldPref = app.preferences.rulerUnits;//stores old measurement preferences so that they can be reset when the script is done.

app.preferences.rulerUnits = Units.PIXELS;

var docSize = new Array('8X10','5X7','2X3','120px X 120px','6X7 Tech Fellows','Passport');

var cropBounds = new Array();

var headMaxBounds = new Array();

var headMinBounds = new Array();

var eyes = new Array();

var lips = new Array();

var cropRatio

var runProg = false;

var tempLayer

var docResize = new Array();

var proceedRunning = true;

var dlg = new Window('dialog','Portriat Guides');

      dlg.alignChildren = ['left','top'];

      dlg.sizeGp = dlg.add('group');

            dlg.sizeGp.orientation = 'row';

            dlg.sizeGp.alignChildren = ['left','top'];

            var sizeDL = dlg.sizeGp.add('dropdownlist',undefined,docSize);

                  sizeDL.selection = 3;

            dlg.sizeGp.docDPIsTxt = dlg.sizeGp.add('statictext',undefined,'DPI:');

            var docDPIeTxt = dlg.sizeGp.add('edittext',undefined,300);

                  docDPIeTxt.size = [50,20];

                  docDPIeTxt.onChange = function(){textToNum(25,3000,this,'int')};

                 

            dlg.sizeGp.crop = dlg.sizeGp.add('radiobutton',undefined,'Crop');

            dlg.sizeGp.guides = dlg.sizeGp.add('radiobutton',undefined,'Add fixed Guides');

            dlg.sizeGp.crop.value = true

                 

      dlg.buttonGp = dlg.add('group');

            dlg.buttonGp.orientation = 'row';

            dlg.buttonGp.alignChildren = ['left','top'];

           

            dlg.buttonGp.okBtn = dlg.buttonGp.add('button',undefined,'Ok');

                  dlg.buttonGp.okBtn.onClick = function(){

                        if(proceedRunning){

                              dlg.close();

                              switch(parseInt(sizeDL.selection)){

                                    case 0:

                                          docResize[0] = 8

                                          break;

                                    case 1:

                                          docResize[0] = 5

                                          break;     

                                    case 2:

                                          docResize[0] = 2

                                          break; 

                                    case 3:

                                          docResize[0] = 1.667

                                          break;     

                                    case 4:

                                          docResize[0] = 6

                                          break;  

                                    case 5:

                                          docResize[0] = 2

                                          break;                                            

                                    };//end switch

                              docResize[1] = parseInt(docDPIeTxt.text);

                              runProg = true;

                              };

                        };

           

            dlg.buttonGp.cancelBtn = dlg.buttonGp.add('button',undefined,'Cancel');

                  dlg.buttonGp.cancelBtn.onClick = function(){dlg.close()};

                 

            sizeDL.onChange = function(){

                  switch(parseInt(sizeDL.selection)){

                                    case 0:

                                          docDPIeTxt.text = 300;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = true;

                                          break;

                                    case 1:

                                          docDPIeTxt.text = 300;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = true;

                                          break;

                                    case 2:

                                          docDPIeTxt.text = 300;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = true;   

                                          break;

                                    case 3:

                                          docDPIeTxt.text = 72;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = false;       

                                          break;

                                    case 4:

                                          docDPIeTxt.text = 350;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = false;   

                                          break;

                                    case 5:

                                          docDPIeTxt.text = 300;

                                          dlg.sizeGp.docDPIsTxt.enabled = docDPIeTxt.enabled = true;

                                          break;                                         

                                      

                  };//end switch

            };//end function sizeDL.onChange

           

dlg.show();

if(runProg && app.documents.length>0){

      var docRef = activeDocument;

      createTempLayer()

     

      //makeLines (leftG, topG, rightG, bottomG)

      makeLines ( vAdj (904), vAdj (1425), vAdj (1937), vAdj (1425))//eyes

      makeLines ( vAdj (1013), vAdj (1973), vAdj (1830), vAdj (1973))//lips

     

      switch(parseInt(sizeDL.selection)){

            case 0://8X10

                  makeLines ( vAdj (164), vAdj (277), vAdj (2669), vAdj (277))//top

                  makeLines ( vAdj (2669), vAdj (277), vAdj (2669), vAdj (3408))//right

                  makeLines ( vAdj (2669), vAdj (3408), vAdj (164), vAdj (3408))//bottom

                  makeLines ( vAdj (164), vAdj (3408), vAdj (164), vAdj (277))//left

                  break;             

            case 1://5X7

                  makeLines ( vAdj (212), vAdj (272), vAdj (2620), vAdj (272))//top

                  makeLines ( vAdj (2620), vAdj (272), vAdj (2620), vAdj (3643))//right

                  makeLines ( vAdj (2620), vAdj (3643), vAdj (212), vAdj (3643))//bottom

                  makeLines ( vAdj (212), vAdj (3643), vAdj (212), vAdj (272))//left

                  break; 

            case 2://2X3

                  makeLines ( vAdj (212), vAdj (250), vAdj (2620), vAdj (250))//top

                  makeLines ( vAdj (2620), vAdj (250), vAdj (2620), vAdj (3865))//right

                  makeLines ( vAdj (2620), vAdj (3865), vAdj (212), vAdj (3865))//bottom

                  makeLines ( vAdj (212), vAdj (3865), vAdj (212), vAdj (250))//left           

                  break;

            case 3://120X120

                  makeLines ( vAdj (86), vAdj (290), vAdj (2746), vAdj (290))//top

                  makeLines ( vAdj (2746), vAdj (290), vAdj (2746), vAdj (2950))//right

                  makeLines ( vAdj (2746), vAdj (2950), vAdj (86), vAdj (2950))//bottom

                  makeLines ( vAdj (86), vAdj (2950), vAdj (86), vAdj (290))//left

                  break;

            case 4://tech 6X7

                  makeLines ( vAdj (156), vAdj (310), vAdj (2686), vAdj (310))//top

                  makeLines ( vAdj (2686), vAdj (310), vAdj (2686), vAdj (3250))//right

                  makeLines ( vAdj (2686), vAdj (3250), vAdj (156), vAdj (3250))//bottom

                  makeLines ( vAdj (156), vAdj (3250), vAdj (156), vAdj (310))//bottom

                  break;

            case 5://passport

                  makeLines ( vAdj (29), vAdj (294), vAdj (2794), vAdj (294))//top

                  makeLines ( vAdj (2794), vAdj (294), vAdj (2794), vAdj (3069))//right

                  makeLines ( vAdj (2794), vAdj (3069), vAdj (29), vAdj (3069))//bottom

                  makeLines ( vAdj (29), vAdj (3069), vAdj (29), vAdj (294))//bottom

                  break;                 

     

            };//end switch

     

      setLayer ()

     

      tempLayer.opacity = 30;

      transformLayer();

      var cropBounds = [parseFloat (tempLayer.bounds[0]),parseFloat (tempLayer.bounds[1]),parseFloat (tempLayer.bounds[2]),parseFloat (tempLayer.bounds[3])];

      if(dlg.sizeGp.crop.value){

            cropPort ();

            tempLayer.remove();

            app.preferences.rulerUnits = Units.INCHES;

            docRef.resizeImage (docResize[0], undefined, docResize[1])

            }//end if

      else{

            vertG (cropBounds[0])

            vertG (cropBounds[2])

            horG (cropBounds[1])

            horG (cropBounds[3])

            tempLayer.remove();

            };//end else

      app.preferences.rulerUnits = oldPref

      };//end function runProgram

function createTempLayer(){

      // Select ellipse tool=======================================================

      var idslct = charIDToTypeID( "slct" );

          var desc4 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref3 = new ActionReference();

              var idellipseTool = stringIDToTypeID( "ellipseTool" );

              ref3.putClass( idellipseTool );

          desc4.putReference( idnull, ref3 );

          var iddontRecord = stringIDToTypeID( "dontRecord" );

          desc4.putBoolean( iddontRecord, true );

          var idforceNotify = stringIDToTypeID( "forceNotify" );

          desc4.putBoolean( idforceNotify, true );

      executeAction( idslct, desc4, DialogModes.NO );

// Make outer oval   =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc41 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref12 = new ActionReference();

        var idcontentLayer = stringIDToTypeID( "contentLayer" );

        ref12.putClass( idcontentLayer );

    desc41.putReference( idnull, ref12 );

    var idUsng = charIDToTypeID( "Usng" );

        var desc42 = new ActionDescriptor();

        var idType = charIDToTypeID( "Type" );

            var desc43 = new ActionDescriptor();

            var idClr = charIDToTypeID( "Clr " );

                var desc44 = new ActionDescriptor();

                var idRd = charIDToTypeID( "Rd  " );

                desc44.putDouble( idRd, 0.000000 );

                var idGrn = charIDToTypeID( "Grn " );

                desc44.putDouble( idGrn, 255.000000 );

                var idBl = charIDToTypeID( "Bl  " );

                desc44.putDouble( idBl, 0.000000 );

            var idRGBC = charIDToTypeID( "RGBC" );

            desc43.putObject( idClr, idRGBC, desc44 );

        var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

        desc42.putObject( idType, idsolidColorLayer, desc43 );

        var idShp = charIDToTypeID( "Shp " );

            var desc45 = new ActionDescriptor();

            var idTop = charIDToTypeID( "Top " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc45.putUnitDouble( idTop, idPxl, vAdj (503.000000) );

            var idLeft = charIDToTypeID( "Left" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc45.putUnitDouble( idLeft, idPxl, vAdj (807.000000) );

            var idBtom = charIDToTypeID( "Btom" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc45.putUnitDouble( idBtom, idPxl, vAdj (2308.000000) );

            var idRght = charIDToTypeID( "Rght" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc45.putUnitDouble( idRght, idPxl, vAdj (2025.000000) );

        var idElps = charIDToTypeID( "Elps" );

        desc42.putObject( idShp, idElps, desc45 );

        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );

            var desc46 = new ActionDescriptor();

            var idstrokeStyleVersion = stringIDToTypeID( "strokeStyleVersion" );

            desc46.putInteger( idstrokeStyleVersion, 2 );

            var idstrokeEnabled = stringIDToTypeID( "strokeEnabled" );

            desc46.putBoolean( idstrokeEnabled, false );

            var idfillEnabled = stringIDToTypeID( "fillEnabled" );

            desc46.putBoolean( idfillEnabled, true );

            var idstrokeStyleLineWidth = stringIDToTypeID( "strokeStyleLineWidth" );

            var idPnt = charIDToTypeID( "#Pnt" );

            desc46.putUnitDouble( idstrokeStyleLineWidth, idPnt, 8.000000 );

            var idstrokeStyleLineDashOffset = stringIDToTypeID( "strokeStyleLineDashOffset" );

            var idPnt = charIDToTypeID( "#Pnt" );

            desc46.putUnitDouble( idstrokeStyleLineDashOffset, idPnt, 0.000000 );

            var idstrokeStyleMiterLimit = stringIDToTypeID( "strokeStyleMiterLimit" );

            desc46.putDouble( idstrokeStyleMiterLimit, 100.000000 );

            var idstrokeStyleLineCapType = stringIDToTypeID( "strokeStyleLineCapType" );

            var idstrokeStyleLineCapType = stringIDToTypeID( "strokeStyleLineCapType" );

            var idstrokeStyleButtCap = stringIDToTypeID( "strokeStyleButtCap" );

            desc46.putEnumerated( idstrokeStyleLineCapType, idstrokeStyleLineCapType, idstrokeStyleButtCap );

            var idstrokeStyleLineJoinType = stringIDToTypeID( "strokeStyleLineJoinType" );

            var idstrokeStyleLineJoinType = stringIDToTypeID( "strokeStyleLineJoinType" );

            var idstrokeStyleMiterJoin = stringIDToTypeID( "strokeStyleMiterJoin" );

            desc46.putEnumerated( idstrokeStyleLineJoinType, idstrokeStyleLineJoinType, idstrokeStyleMiterJoin );

            var idstrokeStyleLineAlignment = stringIDToTypeID( "strokeStyleLineAlignment" );

            var idstrokeStyleLineAlignment = stringIDToTypeID( "strokeStyleLineAlignment" );

            var idstrokeStyleAlignOutside = stringIDToTypeID( "strokeStyleAlignOutside" );

            desc46.putEnumerated( idstrokeStyleLineAlignment, idstrokeStyleLineAlignment, idstrokeStyleAlignOutside );

            var idstrokeStyleScaleLock = stringIDToTypeID( "strokeStyleScaleLock" );

            desc46.putBoolean( idstrokeStyleScaleLock, false );

            var idstrokeStyleStrokeAdjust = stringIDToTypeID( "strokeStyleStrokeAdjust" );

            desc46.putBoolean( idstrokeStyleStrokeAdjust, false );

            var idstrokeStyleLineDashSet = stringIDToTypeID( "strokeStyleLineDashSet" );

                var list3 = new ActionList();

            desc46.putList( idstrokeStyleLineDashSet, list3 );

            var idstrokeStyleBlendMode = stringIDToTypeID( "strokeStyleBlendMode" );

            var idBlnM = charIDToTypeID( "BlnM" );

            var idNrml = charIDToTypeID( "Nrml" );

            desc46.putEnumerated( idstrokeStyleBlendMode, idBlnM, idNrml );

            var idstrokeStyleOpacity = stringIDToTypeID( "strokeStyleOpacity" );

            var idPrc = charIDToTypeID( "#Prc" );

            desc46.putUnitDouble( idstrokeStyleOpacity, idPrc, 100.000000 );

            var idstrokeStyleContent = stringIDToTypeID( "strokeStyleContent" );

                var desc47 = new ActionDescriptor();

                var idClr = charIDToTypeID( "Clr " );

                    var desc48 = new ActionDescriptor();

                    var idRd = charIDToTypeID( "Rd  " );

                    desc48.putDouble( idRd, 255.000000 );

                    var idGrn = charIDToTypeID( "Grn " );

                    desc48.putDouble( idGrn, 0.000000 );

                    var idBl = charIDToTypeID( "Bl  " );

                    desc48.putDouble( idBl, 0.000000 );

                var idRGBC = charIDToTypeID( "RGBC" );

                desc47.putObject( idClr, idRGBC, desc48 );

            var idsolidColorLayer = stringIDToTypeID( "solidColorLayer" );

            desc46.putObject( idstrokeStyleContent, idsolidColorLayer, desc47 );

            var idstrokeStyleResolution = stringIDToTypeID( "strokeStyleResolution" );

            desc46.putDouble( idstrokeStyleResolution, 300.000000 );

        var idstrokeStyle = stringIDToTypeID( "strokeStyle" );

        desc42.putObject( idstrokeStyle, idstrokeStyle, desc46 );

    var idcontentLayer = stringIDToTypeID( "contentLayer" );

    desc41.putObject( idUsng, idcontentLayer, desc42 );

executeAction( idMk, desc41, DialogModes.NO );

// Inner oval =======================================================

var idSbtF = charIDToTypeID( "SbtF" );

    var desc55 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref14 = new ActionReference();

        var idPath = charIDToTypeID( "Path" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref14.putEnumerated( idPath, idOrdn, idTrgt );

    desc55.putReference( idnull, ref14 );

    var idT = charIDToTypeID( "T   " );

        var desc56 = new ActionDescriptor();

        var idTop = charIDToTypeID( "Top " );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc56.putUnitDouble( idTop, idPxl, vAdj ( 503.000000) );

        var idLeft = charIDToTypeID( "Left" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc56.putUnitDouble( idLeft, idPxl, vAdj (912.000000) );

        var idBtom = charIDToTypeID( "Btom" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc56.putUnitDouble( idBtom, idPxl, vAdj (2308.000000) );

        var idRght = charIDToTypeID( "Rght" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc56.putUnitDouble( idRght, idPxl, vAdj (1920.000000) );

    var idElps = charIDToTypeID( "Elps" );

    desc55.putObject( idT, idElps, desc56 );

executeAction( idSbtF, desc55, DialogModes.NO );

      //Select retangle tool =======================================================

      var idslct = charIDToTypeID( "slct" );

          var desc15 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref6 = new ActionReference();

              var idrectangleTool = stringIDToTypeID( "rectangleTool" );

              ref6.putClass( idrectangleTool );

          desc15.putReference( idnull, ref6 );

          var iddontRecord = stringIDToTypeID( "dontRecord" );

          desc15.putBoolean( iddontRecord, true );

          var idforceNotify = stringIDToTypeID( "forceNotify" );

          desc15.putBoolean( idforceNotify, true );

      executeAction( idslct, desc15, DialogModes.NO );

      };//end function createTempLayer

function makeLines(leftG,topG,rightG,bottomG){

      var idAddT = charIDToTypeID( "AddT" );

          var desc140 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref39 = new ActionReference();

              var idPath = charIDToTypeID( "Path" );

              var idOrdn = charIDToTypeID( "Ordn" );

              var idTrgt = charIDToTypeID( "Trgt" );

              ref39.putEnumerated( idPath, idOrdn, idTrgt );

          desc140.putReference( idnull, ref39 );

          var idT = charIDToTypeID( "T   " );

              var desc141 = new ActionDescriptor();

              var idStrt = charIDToTypeID( "Strt" );

                  var desc142 = new ActionDescriptor();

                  var idHrzn = charIDToTypeID( "Hrzn" );

                  var idPxl = charIDToTypeID( "#Pxl" );

                  desc142.putUnitDouble( idHrzn, idPxl, leftG );

                  var idVrtc = charIDToTypeID( "Vrtc" );

                  var idPxl = charIDToTypeID( "#Pxl" );

                  desc142.putUnitDouble( idVrtc, idPxl, topG );

              var idPnt = charIDToTypeID( "Pnt " );

              desc141.putObject( idStrt, idPnt, desc142 );

              var idEnd = charIDToTypeID( "End " );

                  var desc143 = new ActionDescriptor();

                  var idHrzn = charIDToTypeID( "Hrzn" );

                  var idPxl = charIDToTypeID( "#Pxl" );

                  desc143.putUnitDouble( idHrzn, idPxl, rightG );

                  var idVrtc = charIDToTypeID( "Vrtc" );

                  var idPxl = charIDToTypeID( "#Pxl" );

                  desc143.putUnitDouble( idVrtc, idPxl, bottomG );

              var idPnt = charIDToTypeID( "Pnt " );

              desc141.putObject( idEnd, idPnt, desc143 );

              var idWdth = charIDToTypeID( "Wdth" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc141.putUnitDouble( idWdth, idPxl, 8.000000 );

          var idLn = charIDToTypeID( "Ln  " );

          desc140.putObject( idT, idLn, desc141 );

      executeAction( idAddT, desc140, DialogModes.NO );     

      }//end function makeLines

function setLayer(){

      // Set Opacity =======================================================

     var idsetd = charIDToTypeID( "setd" );

          var desc38 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref17 = new ActionReference();

              var idLyr = charIDToTypeID( "Lyr " );

              var idOrdn = charIDToTypeID( "Ordn" );

              var idTrgt = charIDToTypeID( "Trgt" );

              ref17.putEnumerated( idLyr, idOrdn, idTrgt );

          desc38.putReference( idnull, ref17 );

          var idT = charIDToTypeID( "T   " );

              var desc39 = new ActionDescriptor();

              var idOpct = charIDToTypeID( "Opct" );

              var idPrc = charIDToTypeID( "#Prc" );

              desc39.putUnitDouble( idOpct, idPrc, 35.000000 );

          var idLyr = charIDToTypeID( "Lyr " );

          desc38.putObject( idT, idLyr, desc39 );

      executeAction( idsetd, desc38, DialogModes.NO );

      // Deselect paths prior to transform=======================================================

      var idDslc = charIDToTypeID( "Dslc" );

          var desc40 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref18 = new ActionReference();

              var idPath = charIDToTypeID( "Path" );

              ref18.putClass( idPath );

          desc40.putReference( idnull, ref18 );

      executeAction( idDslc, desc40, DialogModes.NO );

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

      var idslct = charIDToTypeID( "slct" );

          var desc43 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref20 = new ActionReference();

              var idHstS = charIDToTypeID( "HstS" );

              var idOrdn = charIDToTypeID( "Ordn" );

              var idPrvs = charIDToTypeID( "Prvs" );

              ref20.putEnumerated( idHstS, idOrdn, idPrvs );

          desc43.putReference( idnull, ref20 );

      executeAction( idslct, desc43, DialogModes.NO );

     

      tempLayer = docRef.activeLayer;

  

      };//end function setlayer

    function transformLayer(){

    try{

        var desc = new ActionDescriptor();

            var ref = new ActionReference();

            ref.putEnumerated( app.charIDToTypeID('Lyr '), app.charIDToTypeID('Ordn'), app.charIDToTypeID('Trgt') );

        desc.putReference( app.charIDToTypeID('null'), ref );

        executeAction( app.charIDToTypeID('Trnf'), desc, DialogModes.ALL );

        }catch(e){

      if (e.toString().match(/User cancelled/)) {

           return -1;

           }else{

          throw e;

          }

      }

      app.displayDialogs = DialogModes.NO;

    };

function cropPort(){

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

      var idslct = charIDToTypeID( "slct" );

          var desc3 = new ActionDescriptor();

          var idnull = charIDToTypeID( "null" );

              var ref1 = new ActionReference();

              var idcropTool = stringIDToTypeID( "cropTool" );

              ref1.putClass( idcropTool );

          desc3.putReference( idnull, ref1 );

          var iddontRecord = stringIDToTypeID( "dontRecord" );

          desc3.putBoolean( iddontRecord, true );

          var idforceNotify = stringIDToTypeID( "forceNotify" );

          desc3.putBoolean( idforceNotify, true );

      executeAction( idslct, desc3, DialogModes.NO );

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

      var idCrop = charIDToTypeID( "Crop" );

          var desc4 = new ActionDescriptor();

          var idT = charIDToTypeID( "T   " );

              var desc5 = new ActionDescriptor();

              var idTop = charIDToTypeID( "Top " );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc5.putUnitDouble( idTop, idPxl, cropBounds[1] );

              var idLeft = charIDToTypeID( "Left" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc5.putUnitDouble( idLeft, idPxl, cropBounds[0] );

              var idBtom = charIDToTypeID( "Btom" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc5.putUnitDouble( idBtom, idPxl, cropBounds[3] );

              var idRght = charIDToTypeID( "Rght" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc5.putUnitDouble( idRght, idPxl, cropBounds[2] );

          var idRctn = charIDToTypeID( "Rctn" );

          desc4.putObject( idT, idRctn, desc5 );

          var idAngl = charIDToTypeID( "Angl" );

          var idAng = charIDToTypeID( "#Ang" );

          desc4.putUnitDouble( idAngl, idAng, 0.000000 );

          var idDlt = charIDToTypeID( "Dlt " );

          desc4.putBoolean( idDlt, false );

          var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );

          var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );

          var idunconstrained = stringIDToTypeID( "unconstrained" );

          desc4.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idunconstrained );

      executeAction( idCrop, desc4, DialogModes.NO );

};//end function cropPort

function textToNum(sMin,sMax,e,par){

    var sHold = sMin;

   

    if(par == 'int'){

        if(isNaN(parseInt(e.text))){

                    proceedRunning = false;

            alert('"' + e.text + '" is not a number\nEnter a value between ' + sMin + '-' + sMax );

            e.text = sMin};

        else{sHold = parseInt(e.text)

            if(sHold < sMin){

                        proceedRunning = false;

                rangeAlert();

                sHold = sMin;               

                }

                  else{proceedRunning = true};

            if(sHold > sMax){

                        proceedRunning = false;

                rangeAlert();

                sHold = sMax;

                }

                  else{proceedRunning = true}

            e.text = sHold;

            };    //end else

        };//end if par

    else{

        if(isNaN(parseFloat(e.text))){

            alert('"' + e.text + '" is not a number\nEnter a value between ' + sMin + '-' + sMax );

            e.text = sMin};

        else{sHold = parseFloat(e.text)

            if(sHold < sMin){

                rangeAlert();

                sHold = sMin;

                };

            if(sHold > sMax){

                rangeAlert();

                sHold = sMax;

                };

            e.text = sHold;

            };    //end else

        };//end else par

    function rangeAlert(){

            proceedRunning = false;

            alert('Number range must be between ' + sMin + '-' + sMax)

            };

};//end function textToNum

function vertG(position){

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

      var idMk = charIDToTypeID( "Mk  " );

          var desc3 = new ActionDescriptor();

          var idNw = charIDToTypeID( "Nw  " );

              var desc4 = new ActionDescriptor();

              var idPstn = charIDToTypeID( "Pstn" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc4.putUnitDouble( idPstn, idPxl, position );

              var idOrnt = charIDToTypeID( "Ornt" );

              var idOrnt = charIDToTypeID( "Ornt" );

              var idVrtc = charIDToTypeID( "Vrtc" );

              desc4.putEnumerated( idOrnt, idOrnt, idVrtc );

          var idGd = charIDToTypeID( "Gd  " );

          desc3.putObject( idNw, idGd, desc4 );

      executeAction( idMk, desc3, DialogModes.NO );

      };//end function vertG

function horG(position){

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

      var idMk = charIDToTypeID( "Mk  " );

          var desc5 = new ActionDescriptor();

          var idNw = charIDToTypeID( "Nw  " );

              var desc6 = new ActionDescriptor();

              var idPstn = charIDToTypeID( "Pstn" );

              var idPxl = charIDToTypeID( "#Pxl" );

              desc6.putUnitDouble( idPstn, idPxl, position );

              var idOrnt = charIDToTypeID( "Ornt" );

              var idOrnt = charIDToTypeID( "Ornt" );

              var idHrzn = charIDToTypeID( "Hrzn" );

              desc6.putEnumerated( idOrnt, idOrnt, idHrzn );

          var idGd = charIDToTypeID( "Gd  " );

          desc5.putObject( idNw, idGd, desc6 );

      executeAction( idMk, desc5, DialogModes.NO );     

      };//end function horG

function vAdj(num){//adjust vector layer to size of document

      var factor = 2832/parseFloat (docRef.width)//2832 is size of test doc.

      return num*factor

      };//end function vAdj

Known Participant
September 16, 2021

This script is so good.
However, I want to change it to the size I want, but I don't know where to change it. The sizes I need are 3x4, 3.5x4.5, 5x5, 5x7 300dpi/cm. Please help me.

Stephen Marsh
Community Expert
Community Expert
May 28, 2019

This requirement:

I have a bulk of portraits images. And I want to crop them all on the same position, same in size, head size, eye position so they all can seem consistent.

Would appear to conflict with this requirement:

I need an automated process for the same. Can you please suggest to me so I can avoid manual work and save a lot of time.

As with most things in photography – if you wish to save work in post-production, you have to get it right at capture.

Here are two professional headshots (not my work, I pixelated them), one by one and overlayed together, you can see that even with "idealised" guides marking top/bottom/left/right/eyes/nostrils/mouth etc., there will be a lot of manual work, even with the aid of various automation routines.

sourabhverma
Known Participant
May 28, 2019

Hi Stephen.

As with most things in photography – if you wish to save work in post-production, you have to get it right at capture.

Yes, I do agree with you. But I have not captured those images. I generally do the post-production only. And I have to be faster than the others :-) and I believe in automation. I know there will be manual work required but It saves a few percents of manual work. Maybe 50% or more than that. :-)


If you know any other plugins for automated cropping. Please suggest.

Stephen Marsh
Community Expert
Community Expert
May 28, 2019

OK, semi-automation is doable, at least you have realistic goals (it sounded otherwise).

Bojan Živković11378569
Community Expert
Community Expert
May 28, 2019

Can we see a few examples? If your shots have head, eye... in different positions then it won't work because using action it is difficult to achieve that kind of consistency in batch process.

macpawel
Participating Frequently
May 28, 2019

As Bojan and Stephen said before it's difficult proces. But you can try this:

use File > Scripts > Load Files into stack option and load as many pictures you want

Crop your document

Exort > Layers to files option allows you to save independent files

But it works if your photos are almost the same

sourabhverma
Known Participant
May 28, 2019

Hi Macpawel,

Thank you, but It will not work for me. As the images are not at the same in size and with same focal length.