Skip to main content
Mattmcquiff
Inspiring
May 24, 2016
Answered

Select Crop Tool and select a ratio (based on Filename)

  • May 24, 2016
  • 6 replies
  • 3899 views

I have lots of files that when I crop them they need to a specific ratio. Currently they are saved to the tool.

I would like to be able to make a shortcut so that it selects the crop tool and selects the ratio from the File name. I can gather the info from the filename.

i.e.  FR10 = a Ratio of 2:3

or

DE20 = 3:4

It does not need to crop the image just select the tool.

I found this to select the tool

The beginning is like this.

if (app.documents.length > 0) {

    var myDocument = activeDocument;

    var fileNameNoExtension = myDocument.name;

   

  fileNameNoExtension = fileNameNoExtension.split( "." );

   

  if ( fileNameNoExtension.length > 1 ) {

      fileNameNoExtension.length--;

    }

    fileNameNoExtension = fileNameNoExtension.join(".");

   

    var BrandString = fileNameNoExtension.substr(0,4);

 

  }

if (/^(FR10|WA35)$/.exec(BrandString)){

    var the_x_Ratio =2

    var the_y_Ratio =3

    }

This topic has been closed for replies.
Correct answer c.pfaffenbichler

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var width = myDocument.width;

var height = myDocument.height;

var rel = 1;

if (myDocument.name.indexOf("AB10") != -1) {var rel = 0.666};

if (myDocument.name.indexOf("CD10") != -1) {var rel = 0.75};

if (myDocument.name.indexOf("EF10") != -1) {var rel = 0.8};

if (myDocument.name.indexOf("CH10") != -1) {var rel = 0.833};

try {

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

var idCrop = charIDToTypeID( "Crop" );

    var desc3 = new ActionDescriptor();

    var idT = charIDToTypeID( "T   " );

        var desc4 = new ActionDescriptor();

        var idTop = charIDToTypeID( "Top " );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idTop, idPxl, 0 );

        var idLeft = charIDToTypeID( "Left" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idLeft, idPxl, (width - height * rel) / 2 );

        var idBtom = charIDToTypeID( "Btom" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idBtom, idPxl, height );

        var idRght = charIDToTypeID( "Rght" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idRght, idPxl, (width - height * rel) / 2 + height * rel );

    var idRctn = charIDToTypeID( "Rctn" );

    desc3.putObject( idT, idRctn, desc4 );

    var idAngl = charIDToTypeID( "Angl" );

    var idAng = charIDToTypeID( "#Ang" );

    desc3.putUnitDouble( idAngl, idAng, 0.000000 );

    var idDlt = charIDToTypeID( "Dlt " );

    desc3.putBoolean( idDlt, false );

    var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );

    var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );

    var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );

    desc3.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );

    var idCnsP = charIDToTypeID( "CnsP" );

    desc3.putBoolean( idCnsP, true );

executeAction( idCrop, desc3, DialogModes.ALL );

} catch (e) {};

//

app.preferences.rulerUnits = originalRulerUnits;

};

Edit: Using the indexOf may be problematic and the if-clauses are inelegant, so a switch-clause would probably be better.

6 replies

tssee
Inspiring
May 25, 2017

I did various tests but I did not have any luck

I would like the crop to be horizontal as in the figure above

thank you

c.pfaffenbichler
Community Expert
Community Expert
May 25, 2017

Quite frankly I think you should start a new thread and post the code you have issues with instead of adding to some old thread.

Mattmcquiff
Inspiring
May 25, 2016

Hmm I'm struggling to get this to behave as I had hoped.

This Is how I currently do it, checking the file name of the document inform of the Brand that I am working on. I click the crop tool. I then use the drop down box in the menu bar to select the crop ratio as it happens I have them pre set to each brand ratio. After clicking it this would be then end of the script and where the user comes in to adjust the crop position etc.

I have about 10 different ratios,

IE

First 4 characters of File name>>>

AB10 = 2:3

CD10 = 3:4

EF10 = 4:5

GH10 = 5:6.

Ideally just like when you select the ratio  from the drop down box it centers itself in image.

Going to play some more. see if I can pass my script on to those that everyone has contributed. Thanks so far!

Matt

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
May 25, 2016

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var width = myDocument.width;

var height = myDocument.height;

var rel = 1;

if (myDocument.name.indexOf("AB10") != -1) {var rel = 0.666};

if (myDocument.name.indexOf("CD10") != -1) {var rel = 0.75};

if (myDocument.name.indexOf("EF10") != -1) {var rel = 0.8};

if (myDocument.name.indexOf("CH10") != -1) {var rel = 0.833};

try {

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

var idCrop = charIDToTypeID( "Crop" );

    var desc3 = new ActionDescriptor();

    var idT = charIDToTypeID( "T   " );

        var desc4 = new ActionDescriptor();

        var idTop = charIDToTypeID( "Top " );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idTop, idPxl, 0 );

        var idLeft = charIDToTypeID( "Left" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idLeft, idPxl, (width - height * rel) / 2 );

        var idBtom = charIDToTypeID( "Btom" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idBtom, idPxl, height );

        var idRght = charIDToTypeID( "Rght" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idRght, idPxl, (width - height * rel) / 2 + height * rel );

    var idRctn = charIDToTypeID( "Rctn" );

    desc3.putObject( idT, idRctn, desc4 );

    var idAngl = charIDToTypeID( "Angl" );

    var idAng = charIDToTypeID( "#Ang" );

    desc3.putUnitDouble( idAngl, idAng, 0.000000 );

    var idDlt = charIDToTypeID( "Dlt " );

    desc3.putBoolean( idDlt, false );

    var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );

    var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );

    var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );

    desc3.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );

    var idCnsP = charIDToTypeID( "CnsP" );

    desc3.putBoolean( idCnsP, true );

executeAction( idCrop, desc3, DialogModes.ALL );

} catch (e) {};

//

app.preferences.rulerUnits = originalRulerUnits;

};

Edit: Using the indexOf may be problematic and the if-clauses are inelegant, so a switch-clause would probably be better.

c.pfaffenbichler
Community Expert
Community Expert
June 10, 2016

This is really working well for me, is there anyway to select last used crop ratio if the filename doesn't fit the filename variable?


I suppose you would have to store the value somewhere, a txt-file or an XML-file or … could work and should be fairly easy to create.

Chuck Uebele
Community Expert
Community Expert
May 24, 2016

Do something like this: create a switch statement to determine what your ratios are going to be, then calculate that ratio based on the size of the image and orientation. Use the Acton manager code to crop the image. Use a 0, 0 point to start the crop in the upper left corner, then your calculations for the other dimensions, using the full width or hight of the image to set the crop. Change the AM code at the bottom to "ALL" to bring up the dialog box, so you can crop. Just be sure to reset the dialogs to "NO", or all dialogs will be popping up!

#target photoshop

var doc = activeDocument

var ratioName = //put your ratio name in here from your file name

switch(ratioName){

    case '2:3'://or whatever you use for determining the ratio

        var rt = doc.height * (2/3);

        var btm = doc.height

        break;

    case '3:2'://or whatever you use for determining the ratio

        rt = doc.width

        btm = doc.width * (2/3)

        break;       

    }

cropImg (rt, btm)

function cropImg(right, bottom){

       var idCrop = charIDToTypeID( "Crop" );

        var desc2 = new ActionDescriptor();

        var idT = charIDToTypeID( "T   " );

            var desc3 = new ActionDescriptor();

            var idTop = charIDToTypeID( "Top " );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc3.putUnitDouble( idTop, idPxl, 0); //leave at 0

            var idLeft = charIDToTypeID( "Left" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc3.putUnitDouble( idLeft, idPxl, 0.000000 ); //leave this at 0 for left side

            var idBtom = charIDToTypeID( "Btom" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc3.putUnitDouble( idBtom, idPxl, bottom); //put variable here for bottom side

            var idRght = charIDToTypeID( "Rght" );

            var idPxl = charIDToTypeID( "#Pxl" );

            desc3.putUnitDouble( idRght, idPxl, right ); //put variable here for right side

        var idRctn = charIDToTypeID( "Rctn" );

        desc2.putObject( idT, idRctn, desc3 );

        var idAngl = charIDToTypeID( "Angl" );

        var idAng = charIDToTypeID( "#Ang" );

        desc2.putUnitDouble( idAngl, idAng, 0.000000 );

        var idDlt = charIDToTypeID( "Dlt " );

        desc2.putBoolean( idDlt, true );

        var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );

        var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );

        var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );

        desc2.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );

        var idCnsP = charIDToTypeID( "CnsP" );

        desc2.putBoolean( idCnsP, true );

    executeAction( idCrop, desc2, DialogModes.ALL ); //All brings up dialog box

    app.displayDialogs = DialogModes.NO; //reset to turn off dialog boxes!!!!

}

JJMack
Community Expert
Community Expert
May 24, 2016

You script put me in an interactive crop set for a 2:3 aspect ratio crop however the crop box is like 1 PX and hard to drag the box out its easy to  accidentally rotate the crop image.

JJMack
Chuck Uebele
Community Expert
Community Expert
May 24, 2016

I most likely forgot to put in a units statement. The equations can be adjusted to fix that if the unit value doesn't.

c.pfaffenbichler
Community Expert
Community Expert
May 24, 2016

// 2016, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

var originalRulerUnits = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var width = myDocument.width;

var height = myDocument.height;

var rel = 0.5;

try {

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

var idCrop = charIDToTypeID( "Crop" );

    var desc3 = new ActionDescriptor();

    var idT = charIDToTypeID( "T   " );

        var desc4 = new ActionDescriptor();

        var idTop = charIDToTypeID( "Top " );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idTop, idPxl, 0 );

        var idLeft = charIDToTypeID( "Left" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idLeft, idPxl, 0 );

        var idBtom = charIDToTypeID( "Btom" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idBtom, idPxl, height );

        var idRght = charIDToTypeID( "Rght" );

        var idPxl = charIDToTypeID( "#Pxl" );

        desc4.putUnitDouble( idRght, idPxl, height * rel );

    var idRctn = charIDToTypeID( "Rctn" );

    desc3.putObject( idT, idRctn, desc4 );

    var idAngl = charIDToTypeID( "Angl" );

    var idAng = charIDToTypeID( "#Ang" );

    desc3.putUnitDouble( idAngl, idAng, 0.000000 );

    var idDlt = charIDToTypeID( "Dlt " );

    desc3.putBoolean( idDlt, false );

    var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );

    var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );

    var idpureAspectRatio = stringIDToTypeID( "pureAspectRatio" );

    desc3.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idpureAspectRatio );

    var idCnsP = charIDToTypeID( "CnsP" );

    desc3.putBoolean( idCnsP, true );

executeAction( idCrop, desc3, DialogModes.ALL );

} catch (e) {};

//

app.preferences.rulerUnits = originalRulerUnits;

};

JJMack
Community Expert
Community Expert
May 24, 2016

If there is no DOM scripting interface you need to look at Action Manager Scriptlistener code to script things.  Many tools can not be selected in Actions not  all things you do is Photoshop will record.   Selecting the crop tool  does not record anything when you record an action so the Scriptlistener does does not record any Action Manager script code. A way around the is selecting a tools Preset. You could create crop tool presets  for example Crop 3:4, Crop 4:3, Crop 2:3, Crop 3:2. Selecting these tool preset will both select the crop tool and also set the aspect ratio.  However there is a Problem with this also.  If your Photoshop tools preset pull-down has Current tool only checked.  You can only select those presets if the crop tool is the current tool.  If "Current Tool Only" is not checked you can select any tool's presets.  You can catch the error if you can not select the preset you know the checkbox is checked and the Crop tool is not selected.

The brush tool also records nothing.  The closest I came to scripting a tools preset is this.

// Note:  This script only works if the correct tool for the preset is currently selected.

//        Or "current tool only" is not checked in Photoshop's  "Tool Options Bar" Presets pull-down list dialog at the bottom left. 

var ToolPresetName = "JJMack soft oval red brush" ; // The Photoshop Tool preset name that you created and saved into a set  

var ToolPresetSet  = "JJMackToolsPresetsSet";       // The SetName.tpl file need to be same folder as this Photoshop script.

try {SelectToolPreset(ToolPresetName);}

catch(e) {

  if (LoadToolPresetSet(ToolPresetSet)) {

  try {SelectToolPreset(ToolPresetName);}

  catch(e) {alert('Was unable to Select the Tools Preset "' + ToolPresetName + '".\nUncheck Preset pulld-down dialog "Current Tool Only" check box');}

  }

  else {alert("Was unable to load Tools Presets Set " + ToolPresetSet);}

}

// =================================================== Helper functions ===================================================== //

function SelectToolPreset(PresetName) {

  // === Select Preset, tool must be selected or 'show current tool only' unchecked  ===

  var desc = new ActionDescriptor();

  var ref = new ActionReference();

  ref.putName( stringIDToTypeID( "toolPreset" ), PresetName );

  desc.putReference( charIDToTypeID( "null" ), ref );

  executeAction( charIDToTypeID( "slct" ), desc, DialogModes.NO );

}

function LoadToolPresetSet(SetName) {

  returncode = true;

  var scriptLocation = String(findScript());

  var path = scriptLocation.substr(0, scriptLocation.lastIndexOf("/") + 1 ) ;

  var SetFile = new File(path + SetName + ".tpl");   // Requited to be in the script's folder

  if (!SetFile.exists) { returncode = false; }

  else {

  try {LoadToolsSet(SetFile);}

  catch(e) { returncode = false; }

  }

  return returncode ;

}

function LoadToolsSet(tplFile) {

  // ========load a set of Tools Presets=========================

  var desc = new ActionDescriptor();

  var ref = new ActionReference();

  ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID( "toolPreset"  ));

  ref.putEnumerated( charIDToTypeID( "capp" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt"  ) );

  desc.putReference( charIDToTypeID( "null" ), ref );

  desc.putPath( charIDToTypeID( "T   " ), new File( tplFile ) );

  desc.putBoolean( charIDToTypeID( "Appe" ), true );

  executeAction( charIDToTypeID( "setd" ), desc, DialogModes.NO );

}

// Find the location where this script resides

function findScript() {

  var where = "";

  try { FORCEERROR = FORCERRROR;}

  catch(err) { where = File(err.fileName);}

  return where ;

}

JJMack
c.pfaffenbichler
Community Expert
Community Expert
May 24, 2016

I think this will need the AM code for a crop with »DialogModes.ALL« and the correctly calculated proportions.