Imaging scripts
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;