Imaging scripts

TX_1121_66__a1scale-basmr.jpg

This image has an embedded scale in the digital file and a standard scale applied

These are JavaScripts to further process digital images. They are written to be placed in the Presets>Scripts within Photoshop and may be run by File>Scripts>Browse.
Recent versions of Photoshop allow for easy straightening of an image we do not recommend you use this script unless you have an early version of the program.

 

 

 

 

Straighten

function findAngle(){
   var lineStart = activeDocument.pathItems[0].subPathItems[0].pathPoints[0].anchor;
   var lineEnd = activeDocument.pathItems[0].subPathItems[0].pathPoints[3].anchor;
   var a = Math.abs(lineStart[0]-lineEnd[0]);
   var o = Math.abs(lineStart[1]-lineEnd[1]);
   var c = (180/Math.PI) * Math.atan2(o,a);
   if(lineStart[1] < lineEnd[1]){//negative angle
      c = -c;
      };
   return c;
};

// reference open document
var docRef = app.activeDocument;

// find the angle from the line
var angle = findAngle();

// straighten the image
docRef.rotateCanvas(angle);

// remove the line used for measuring angle
docRef.activeLayer.remove();

 

Scale image

function findLength(){
   try {
   var lineStart = activeDocument.pathItems[0].subPathItems[0].pathPoints[0].anchor;
   var lineEnd = activeDocument.pathItems[0].subPathItems[0].pathPoints[3].anchor;
   }
   catch(error) {
   		Window.alert("You have to draw a measurement line first");
   		return 0;
   }
   var a = lineStart[0]-lineEnd[0];
   var o = lineStart[1]-lineEnd[1];
   var l = Math.sqrt(a*a + o*o);
   l = l * 25.4 / 72; //correct for points to mm - defaults to points
   return l;
};

// reference open document
displaydDialogs = DialogModes.ALL;
var docRef = app.activeDocument;
var originalUnit = preferences.rulerUnits;
preferences.rulerUnits = Units.MM;
var scale_length = 15;

// Create a variable to test if the user selected cancel
userCancelled = false;

// Create a dialog box and populate it with text and controls
var dlg = new Window('dialog', 'Automatic Image Scaling',[1500,100,1800,230]);
dlg.msgPnl = dlg.add('panel', [25,15,275,110], 'Instructions');

dlg.msgPnl.titleSt = dlg.msgPnl.add('statictext', [15,20,180,40],'Enter the length of scale in mm');
dlg.msgPnl.titleEt = dlg.msgPnl.add('edittext', [185,20,240,40],scale_length);

//dlg.msgPnl.titleSt = dlg.msgPnl.add('statictext', [15,65,1350,130],'Pick an anchor point ;');

dlg.msgPnl.okBtn = dlg.msgPnl.add('button', [20,50,115,80],'OK', {name:'ok'});
dlg.msgPnl.cancelBtn = dlg.msgPnl.add('button', [125,50,225,80],'Cancel', {name:'cancel'});

dlg.msgPnl.titleEt.active=true;

// Check that the number input is within the valid range.
// If OK - continue, else display an error message.
dlg.msgPnl.okBtn.onClick = function() {if(!isNaN(dlg.msgPnl.titleEt.text)){

// If you want to scale above 100mm, change the number in the next "IF"
// to your desired number. Don't forget to also change the alert
// message below if you do.
if(((dlg.msgPnl.titleEt.text)> 0) && ((dlg.msgPnl.titleEt.text)<101))
{this.parent.close(0);}
else {alert("Number must be between 1 and 100"); }}
else {alert("Invalid number input")}};

// Set the cancel variable to true if the user cancels the operation
dlg.msgPnl.cancelBtn.onClick = function() {userCancelled = true;this.parent.close(0);};
// Process the rescaling when OK is pressed
dlg.msgPnl.okBtn.onClick = function() {scale_length = dlg.msgPnl.titleEt.text;this.parent.close(0);};
buttonSelected = dlg.show();

if (userCancelled == false) {
   // find the length from the line
   var length = findLength();
   if (length > 0) {
      // remove the line used for measuring angle
      docRef.activeLayer.remove();
      var current_res = docRef.resolution;
      var new_res = (length/scale_length)*current_res;
      var ImSize = charIDToTypeID( "ImgS" );
      var descriptor = new ActionDescriptor();
      var arg1 = charIDToTypeID( "Rslt" );
      var arg2 = charIDToTypeID( "#Rsl" );
      descriptor.putUnitDouble( arg1, arg2, new_res );
      executeAction( ImSize, descriptor, DialogModes.NO );
      }
   }

//Release references
docRef = null;

//Restore original ruler unit setting
app.preferences.rulerUnits = originalUnit;

 

Draw scale bar

function viewZoomOut() {
	//Other useful codes are ZmIn, FtOn, ActP
	var desc = new ActionDescriptor();
	var ref = new ActionReference();
	ref.putEnumerated(cTID('Mn  '), cTID('MnIt'), cTID('ZmOt'));
	desc.putReference(cTID('null'), ref);
	executeAction(cTID('slct'), desc, DialogModes.NO);
}

function add_border_width(brdr_width) {
   //This function adds a border to the side of the image
   var canvas = cTID("CnvS");
   var descriptor = new ActionDescriptor();
   var arg1 = cTID("Wdth");
   var arg2 = cTID("#Pxl");
   descriptor.putUnitDouble(arg1,arg2,brdr_width);
   arg1 = cTID("Hrzn");
   arg2 = cTID("Hrzl");
   var arg3 = cTID("Left");
   descriptor.putEnumerated(arg1,arg2,arg3); // anchor center left
   arg1 = stringIDToTypeID("canvasExtensionColorType");
   arg2 = stringIDToTypeID("canvasExtensionColorType");
   arg3 = cTID("Wht ");
   descriptor.putEnumerated(arg1,arg2,arg3);
   executeAction(canvas,descriptor,DialogModes.NO);
}

function add_border_height(brdr_height) {
   //This function adds a border to the side of the image
   var canvas = cTID("CnvS");
   var descriptor = new ActionDescriptor();
   var arg1 = cTID("Hght");
   var arg2 = cTID("#Pxl");
   descriptor.putUnitDouble(arg1,arg2,brdr_height);
   arg1 = cTID("Vrtc");
   arg2 = cTID("VrtL");
   var arg3 = cTID("Top ");
   descriptor.putEnumerated(arg1,arg2,arg3); // anchor center top
   arg1 = stringIDToTypeID("canvasExtensionColorType");
   arg2 = stringIDToTypeID("canvasExtensionColorType");
   arg3 = cTID("Wht ");
   descriptor.putEnumerated(arg1,arg2,arg3);
   executeAction(canvas,descriptor,DialogModes.NO);
}

function bar(top,bottom,left,right,color){
   //This function draws a bar (rectangle) and fills it with color
   var arg1, arg2, arg3;
   var descriptor = new ActionDescriptor();
   var rectangle = cTID("setd");
   arg1 = cTID("null");
   var reference = new ActionReference();
   var refarg1 = cTID("Chnl");
   var refarg2 = cTID("fsel");
   reference.putProperty(refarg1,refarg2);
   descriptor.putReference(arg1, reference);
   var objtype = cTID("T   ");
   var subdescriptor = new ActionDescriptor();
   arg1 = cTID("Top ");
   arg2 = cTID("#Pxl");
   subdescriptor.putUnitDouble(arg1,arg2, top); // y top
   arg1 = cTID("Left");
   subdescriptor.putUnitDouble(arg1,arg2, left); // X left
   arg1 = cTID("Btom");
   subdescriptor.putUnitDouble(arg1,arg2, bottom); // Y bottom
   arg1 = cTID("Rght");
   subdescriptor.putUnitDouble(arg1,arg2, right); // X right
   arg2 = cTID("Rctn");
   descriptor.putObject(objtype,arg2,subdescriptor);
   executeAction(rectangle, descriptor, DialogModes.NO);

   dofill = cTID("Fl  ");
   filldescriptor = new ActionDescriptor();
   arg1 = cTID("Usng");
   arg2 = cTID("FlCn");
   arg3 = cTID(color);
   filldescriptor.putEnumerated(arg1,arg2,arg3);
   arg1 = cTID("Opct");
   arg2 = cTID("#Prc");
   filldescriptor.putUnitDouble(arg1,arg2,100.000);
   arg1 = cTID("Md  ");
   arg2 = cTID("BlnM");
   arg3 = cTID("Nrml");
   filldescriptor.putEnumerated(arg1,arg2,arg3);
   executeAction(dofill,filldescriptor,DialogModes.NO);

   //Deselect
   selected = cTID("setd");
   seldescriptor = new ActionDescriptor();
   arg1 = cTID("null");
   selreference = new ActionReference();
   refarg1 = cTID("Chnl");
   refarg2 = cTID("fsel");
   selreference.putProperty(refarg1,refarg2);
   seldescriptor.putReference(arg1,selreference);
   objtype = cTID("T   ");
   arg1 = cTID("Ordn");
   arg2 = cTID("None");
   seldescriptor.putEnumerated(objtype,arg1,arg2);
   executeAction(selected,seldescriptor,DialogModes.NO);
}

function addlogo(xoffset, yoffset, iconwidth) {
   var iconheight = iconwidth;
   var arg1, arg2, arg3;
   var place = cTID( "Plc " );
   var descriptor = new ActionDescriptor();
   arg1 = cTID( "null" );
   descriptor.putPath( arg1, new File( "\\\\austin\\disk\\tnsc\\NPL\\NSF Images\\Documents\\Logos\\UT&T_mark.tif" ) );
   //alert(descriptor.getPath( arg1 ) );
   arg1 = cTID( "FTcs" );
   arg2 = cTID( "QCSt" );
   arg3 = cTID( "Qcsa" );
   descriptor.putEnumerated(arg1,arg2,arg3);
   var subdescriptor = new ActionDescriptor();
   arg1 = cTID( "Hrzn" );
   arg2 = cTID( "#Rlt" );
   subdescriptor.putUnitDouble( arg1, arg2, xoffset );
   arg1 = cTID( "Vrtc" );
   arg2 = cTID( "#Rlt" );
   subdescriptor.putUnitDouble( arg1, arg2, yoffset );
   arg1 = cTID( "Ofst" );
   arg2 = cTID( "Ofst" );
   descriptor.putObject( arg1, arg2, subdescriptor );
   arg1 = cTID( "Wdth" );
   arg2 = cTID( "#Prc" );
   descriptor.putUnitDouble( arg1, arg2, iconwidth );
   arg1 = cTID( "Hght" );
   arg2 = cTID( "#Prc" );
   descriptor.putUnitDouble( arg1, arg2, iconheight );
   executeAction( place, descriptor, DialogModes.NO );
}

function addtext(x,y,size,text,orient) {
	text_layer=docRef.artLayers.add();
	text_layer.kind = LayerKind.TEXT;
	textColor = new SolidColor;
	textColor.rgb.red = 0;
	textColor.rgb.green = 0;
	textColor.rgb.blue = 0;
	text_layer.textItem.color = textColor;
	text_layer.textItem.kind=TextType.POINTTEXT; 

	text_layer.textItem.position = Array(x, y);
	text_layer.textItem.size = size;
	if (orient == "v" ) {
	   text_layer.textItem.direction = Direction.VERTICAL;
	   text_layer.rotate(180.0,AnchorPosition.MIDDLECENTER);
	} else {
	   text_layer.textItem.direction = Direction.HORIZONTAL;
	}
	//text_layer.textItem.font = "ArialMT";
	text_layer.textItem.font = "Helvetica";
	text_layer.textItem.contents=text;
}

function flatten() {
   var arg1 = cTID("FltI");
   executeAction(arg1,undefined, DialogModes.NO);
}

function cTID(s) {return app.charIDToTypeID(s);}  

//********************************************************
// Main
//********************************************************
// reference open document
var startRulerUnits = app.preferences.rulerUnits
var startTypeUnits = app.preferences.typeUnits
var startDisplayDialogs = app.displayDialogs
var docRef = app.activeDocument;
preferences.rulerUnits = Units.PIXELS;
preferences.typeUnits = TypeUnits.MM;

//Zoom out first - this fixes a little bug in the place function
viewZoomOut();

//The image file being inserted has is 93x108 pixels at 72 pixels/inch
//  These values are hardwired in this script, and
//  must be changed here if different images are used
var logo_width = 93;
var logo_height = 108;
var logo_res = 72;

var current_res = docRef.resolution;
var current_height = docRef.height;
var current_width = docRef.width;
var aspect = current_height/current_width;

//*****************************************************************************
//This is not particularly pretty, but vertical and horizontal scale
//  annotation is not Photoshop's strong point
//*****************************************************************************
if (aspect >= 1.0) { //Taller than wide
   // Scale the new edge at 150 pixels for every 1000 pixels in the image width
   var addition = current_width*150/1000;
   var add_width = current_width + addition;
   // Reserve the bottom 1/4 of the border for icons
   var icon_block_ht = current_height/5;
   var scale_block_ht = current_height - 2*icon_block_ht;
   // Calculate offsets in points for the icon
   var current_w_pnts = 72*current_width/current_res;
   var current_h_pnts = 72*current_height/current_res;
   var addition_pnts = 72*addition/current_res;
   var x_offset = current_w_pnts/2;
   var y_offset = current_h_pnts/2 - current_h_pnts/8;

   var newht = logo_height * (current_res/72);
   if (newht < current_height) {
      correction = 1;
   } else {
      correction = current_height/newht;
   }

   //Scale the logo smart object
   var iwidth = 100 * addition/(correction * logo_width * (current_res/logo_res));

   //Calculate the scale factors
   var current_res = current_res/25.4;
   var mm_height = scale_block_ht/current_res;
   var scale_height = Math.floor(mm_height);
   var drawarea_bottom;
   var drawarea_top;
   var drawarea_left;
   var drawarea_right;
   var Q1, Q2, Q3;
   var arg1, arg2, arg3;

   add_border_width(add_width);
   addlogo(x_offset,y_offset,iwidth);
   docRef.revealAll;
   flatten();

   if (scale_height < 4) {
      if (scale_height < 1) {
         alert("can't make scale - image less than 1 mm");
      } else {
         scale_height = 1;
         scale_in_pixels = scale_height*current_res;
         buffer = (scale_block_ht - scale_in_pixels)/2;
         drawarea_bottom = scale_block_ht-buffer;
         drawarea_top = drawarea_bottom - scale_in_pixels;
         drawarea_left = current_width +(5*addition/12);
         drawarea_right = drawarea_left + (addition/6);
         bar(drawarea_top,drawarea_bottom,drawarea_left,drawarea_right,"Blck");

         var textsize = scale_height/2;
         if (72*textsize > addition) textsize = textsize/4;
         var text_shift = (textsize/10)*current_res;

         var xpos = drawarea_right+addition/12;
         addtext(xpos,drawarea_bottom+text_shift,textsize,"0","h");
         addtext(xpos,drawarea_top+text_shift,textsize,"1","h");
         addtext(drawarea_left-(addition/6),drawarea_bottom-text_shift*3,textsize,"millimeter","v");
      }
   } else {
      while (scale_height%4 != 0) {
         --scale_height;
      }
      if (scale_height > 40) {
         while (scale_height%40 != 0) {
            --scale_height;
         }
      } else
      if (scale_height > 20 ) {
         while (scale_height%20 != 0) {
           --scale_height;
         }
      } else
      if (scale_height > 8 ) {
         while (scale_height%8 != 0 || scale_height == 16) {
            --scale_height;
         }
      }

      scale_in_pixels = scale_height*current_res;
      buffer = (scale_block_ht - scale_in_pixels)/2;
      drawarea_bottom = scale_block_ht - buffer;
      drawarea_top = buffer;
      drawarea_left = current_width + (5*addition/12);
      drawarea_right = drawarea_left + (addition/6);
      Q1 = drawarea_bottom - scale_in_pixels/4;
      Q2 = drawarea_bottom - scale_in_pixels/2;
      Q3 = drawarea_bottom - 3*scale_in_pixels/4;
      bar(drawarea_top,drawarea_bottom,drawarea_left,drawarea_right,"Blck");
      bar(Q1+2,drawarea_bottom-4,drawarea_left+4,drawarea_right-4,"Wht ");
      bar(Q3+2,Q2-4,drawarea_left+4,drawarea_right-4,"Wht ");

      var textsize = scale_height/6;
      var text_shift = (textsize/6)*current_res;
      var xpos = drawarea_right+(addition/12);
      addtext(xpos,drawarea_bottom+text_shift,textsize,"0","h");
      addtext(xpos,Q1+text_shift,textsize,(scale_height/4),"h");
      addtext(xpos,Q2+text_shift,textsize,(scale_height/2),"h");
      addtext(xpos,Q3+text_shift,textsize,(3*scale_height/4),"h");
      addtext(xpos,drawarea_top+text_shift,textsize,scale_height,"h");
      addtext(drawarea_left-(addition/6),(Q1+Q2)/2,textsize,"millimeters","v");
   }
} else { //Wider than tall
   //*****************************************************************************
   // Scale the new edge at 150 pixels for every 1000 pixels in the image width
   var addition = current_height*150/1000;
   var add_height = current_height + addition;
   // Reserve the left 1/4 of the border for icons
   var icon_block_w = current_width/4;
   var scale_block_w = current_width - icon_block_w;
   // Calculate offsets in points for the icon
   var current_w_pnts = 72*current_width/current_res;
   var current_h_pnts = 72*current_height/current_res;
   var addition_pnts = 72*addition/current_res; 

   var x_offset = -current_w_pnts/2 + current_w_pnts/20;
   var y_offset = current_h_pnts/2;

   var newht = logo_height * (current_res/72);
   if (newht < current_height) {
      correction = 1;
   } else {
      correction = current_height/newht;
   }

   //Scale the logo smart object
   var iheight = 75* addition/(correction * logo_height * (current_res/logo_res));

   //Calculate the scale factors
   var current_res = current_res/25.4;
   var mm_width = scale_block_w/current_res;
   var scale_width = Math.floor(mm_width);
   var drawarea_bottom;
   var drawarea_top;
   var drawarea_left;
   var drawarea_right;
   var Q1, Q2, Q3;
   var arg1, arg2, arg3;

   add_border_height(add_height);
   addlogo(x_offset,y_offset,iheight);
   docRef.revealAll;
   flatten();

   if (scale_width < 4) {
      if (scale_width < 1) {
         alert("can't make scale - image less than 1 mm");
      } else {
         scale_width = 1;
         scale_in_pixels = scale_width*current_res;
         buffer = icon_block_w;
         drawarea_left = 2*buffer;
         drawarea_right = 2*buffer + scale_in_pixels;
         drawarea_bottom = (current_height + addition) - 5*addition/12;
         drawarea_top = drawarea_bottom - addition/6;
         bar(drawarea_top,drawarea_bottom,drawarea_left,drawarea_right,"Blck");

         var textsize = scale_width/2;
         if (72*textsize > addition) textsize = textsize/4;
         var text_shift = (textsize/12)*current_res;

         var ypos = drawarea_top-(addition/12);
         addtext(drawarea_left-text_shift,ypos,textsize,"0","h");
         addtext(drawarea_right-text_shift,ypos,textsize,scale_width,"h");
         addtext(drawarea_left+3*text_shift,drawarea_bottom+(addition/3),textsize,"millimeter","h");
      }
   } else {
      while (scale_width%4 != 0) {
         --scale_width;
      }
      if (scale_width > 40) {
         while (scale_width%40 != 0) {
            --scale_width;
         }
      } else
      if (scale_width > 20 ) {
         while (scale_width%20 != 0) {
           --scale_width;
         }
      } else
      if (scale_width > 8 ) {
         while (scale_width%8 != 0 || scale_width == 16) {
            --scale_width;
         }
      }
      scale_in_pixels = scale_width*current_res;
      buffer = icon_block_w;
      drawarea_left = buffer;
      drawarea_right = buffer + scale_in_pixels;
      drawarea_bottom = (current_height + addition) - 5*addition/12;
      drawarea_top = drawarea_bottom - addition/6;
      Q1 = drawarea_left + scale_in_pixels/4;
      Q2 = drawarea_left + scale_in_pixels/2;
      Q3 = drawarea_left + 3*scale_in_pixels/4;
      bar(drawarea_top,drawarea_bottom,drawarea_left,drawarea_right,"Blck");
      bar(drawarea_top + 2,drawarea_bottom - 2,Q1 - 2, Q2 - 2, "Wht ");
      bar(drawarea_top + 2,drawarea_bottom - 2,Q3 - 2, drawarea_right-2, "Wht ");

      var textsize = scale_width/10;
      var text_shift = (textsize/10)*current_res;

      var ypos = drawarea_top-(addition/12);
      addtext(drawarea_left-text_shift,ypos,textsize,"0","h");
      addtext(Q1-text_shift,ypos,textsize,(scale_width/4),"h");
      addtext(Q2-text_shift,ypos,textsize,(scale_width/2),"h");
      addtext(Q3-text_shift,ypos,textsize,(3*scale_width/4),"h");
      addtext(drawarea_right-text_shift,ypos,textsize,scale_width,"h");
      addtext((Q1+Q2)/2 + 5*text_shift,drawarea_bottom+(addition/3),textsize,"millimeters","h");
   }
}

//************************************************************************
flatten();
//Relaease references
docRef = null;
//Restore original ruler unit setting;
preferences.rulerUnits = startRulerUnits;
preferences.TypeUnits = startTypeUnits;
displayDialogs = startDisplayDialogs;