Copy link to clipboard
Copied
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
}
...
// 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") !
Copy link to clipboard
Copied
I think this will need the AM code for a crop with »DialogModes.ALL« and the correctly calculated proportions.
Copy link to clipboard
Copied
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 ;
}
Copy link to clipboard
Copied
// 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;
};
Copy link to clipboard
Copied
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!!!!
}
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
I most likely forgot to put in a units statement. The equations can be adjusted to fix that if the unit value doesn't.
Copy link to clipboard
Copied
When I set units from inches to pixels the image did not move on the display or turn gray. However the Cropping overlay did not show till I clicked on the image. Then I could see the cropping overlay controls and rule of thirds guides,
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
// 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.
Copy link to clipboard
Copied
Many Thanks for that is working almost as expected. One odd thing, when it selects the crop I see it without the crop markers and I must select tap the pointer in the area for the markers. Can this be made to happen by default.
Copy link to clipboard
Copied
Hadn’t noticed that, seems it’s caused by not selecting the Crop Tool before invoking the Crop, please try this:
// 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};
// =======================================================
var idslct = charIDToTypeID( "slct" );
var desc5 = new ActionDescriptor();
var ref2 = new ActionReference();
ref2.putClass( stringIDToTypeID( "cropTool" ) );
desc5.putReference( charIDToTypeID( "null" ), ref2 );
desc5.putBoolean( stringIDToTypeID( "dontRecord" ), true );
desc5.putBoolean( stringIDToTypeID( "forceNotify" ), true );
executeAction( idslct, desc5, DialogModes.NO );
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;
};
Copy link to clipboard
Copied
Perfect!!
Many Thanks
Matt
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
At the moment it defaults to 1:1 Can you collect the current ratio at the beginning of the script without the need of a text file?
Copy link to clipboard
Copied
Hm, might be possible, I guess I overthought the issue.
Have you tried leaving out the pertinent section in the AM-code?
Copy link to clipboard
Copied
Sorry not sure what that bit is?
Copy link to clipboard
Copied
I may not be able to look into the issue for a few days, maybe you should start new thread to get others’ attention.
Copy link to clipboard
Copied
Yes no worries, thanks for you help though, its been a real help!
Copy link to clipboard
Copied
If the Crop Tool is selected you can use below code to determine the settings and then isolate the one/s you actually want to check out and use those in your Script.
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var currentToolOpt = applicationDesc.getObjectValue(stringIDToTypeID("currentToolOptions"));
checkDesc2(currentToolOpt.getObjectValue(currentToolOpt.getKey(0)));
////////////////////////////////////
////// based on code by michael l hale //////
function checkDesc2 (theDesc) {
var c = theDesc.count;
var str = '';
for(var i=0;i<c;i++){ //enumerate descriptor's keys
str = str + 'Key '+i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)+'\n';
};
alert("desc\n\n"+str);
};
////// check //////
function getValues (theDesc, theNumber) {
switch (theDesc.getType(theDesc.getKey(theNumber))) {
case DescValueType.ALIASTYPE:
return theDesc.getPath(theDesc.getKey(theNumber));
break;
case DescValueType.BOOLEANTYPE:
return theDesc.getBoolean(theDesc.getKey(theNumber));
break;
case DescValueType.CLASSTYPE:
return theDesc.getClass(theDesc.getKey(theNumber));
break;
case DescValueType.DOUBLETYPE:
return theDesc.getDouble(theDesc.getKey(theNumber));
break;
case DescValueType.ENUMERATEDTYPE:
return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
break;
case DescValueType.INTEGERTYPE:
return theDesc.getInteger(theDesc.getKey(theNumber));
break;
case DescValueType.LISTTYPE:
return theDesc.getList(theDesc.getKey(theNumber));
break;
case DescValueType.OBJECTTYPE:
return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
break;
case DescValueType.RAWTYPE:
return theDesc.getReference(theDesc.getData(theNumber));
break;
case DescValueType.REFERENCETYPE:
return theDesc.getReference(theDesc.getKey(theNumber));
break;
case DescValueType.STRINGTYPE:
return theDesc.getString(theDesc.getKey(theNumber));
break;
case DescValueType.UNITDOUBLE:
return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
break;
default:
break;
};
};
Copy link to clipboard
Copied
Sorry should I use the code above to test on its own or use in the exisiting script? Currently I get an error on line 32
Crop was selected first
Error 25: Expected: ).
Line: 32
-> return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStr ingID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
Copy link to clipboard
Copied
Use it to check out the properties available.
It seems several unwanted spaces were introduced when I copy/pasted the code, please correct those manually (in the line in question it should be »typeIDToStringID« instead of »typeIDToStr ingID« for example).
Copy link to clipboard
Copied
I've ran it there were a few other spaces, I can see from this the Values I need are Key 3 (width) and key 5 (height) I'm still not sure how to apply this to my script though.
Copy link to clipboard
Copied
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var applicationDesc = executeActionGet(ref);
var currentToolOpt = applicationDesc.getObjectValue(stringIDToTypeID("currentToolOptions"));
var settings = currentToolOpt.getObjectValue(currentToolOpt.getKey(0));
alert (settings.getUnitDoubleValue(settings.getKey(1)));
alert (settings.getUnitDoubleValue(settings.getKey(2)));
Find more inspiration, events, and resources on the new Adobe Community
Explore Now