ScaleBar modification
Posted by Divakar Ramachandran on Aug 13, 2006; 6:58am
URL: http://imagej.273.s1.nabble.com/ScaleBar-modification-tp3701848.html
I have made a small modification to ScaleBar.java to include an option for background and to handle the 'micron' units of Digital Micrograph. I have been using this as a plugin 'ScaleBar_Plus' and am attaching the modified code, hoping others may find it useful.
Divakar
-- ScaleBar_Plus.java --
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.measure.*;
import java.awt.event.*;
import ij.plugin.PlugIn;
/*
* ScaleBar_Plus.java
*
* Modified version of ScaleBar.java on April 23, 2006, 12:57 AM
*
* This provides additional function of setting the background for the scale marker.
* Defaults for font, color and scale marker position are also changed.
*/
public class ScaleBar_Plus implements PlugIn {
static final String[] locations = {"Upper Right", "Lower Right", "Lower Left", "Upper Left", "At Selection"};
static final int UPPER_RIGHT=0, LOWER_RIGHT=1, LOWER_LEFT=2, UPPER_LEFT=3, AT_SELECTION=4;
static final String[] colors = {"White","Black","Light Gray","Gray","Dark Gray","Red","Green","Blue","Yellow"};
static final String[] checkboxLabels = {"Bold Text", "Hide Text"};
static double barWidth;
static int defaultBarHeight = 3;
static int barHeightInPixels = defaultBarHeight;
// Div., change default to lower right
static String location = locations[LOWER_RIGHT];
// Div., change default for marker to black
static String color = colors[1];
// Div., add variable to hold bkgnd color; set default to white bkgnd
static String bcolor = colors[0];
static boolean boldText = true;
static boolean hideText;
static int fontSize;
static boolean labelAll;
ImagePlus imp;
double imageWidth;
double mag;
int xloc, yloc;
int barWidthInPixels;
int roiX=-1, roiY, roiWidth, roiHeight;
boolean[] checkboxStates = new boolean[2];
public void run(String arg) {
imp = WindowManager.getCurrentImage();
if (imp!=null) {
if (showDialog(imp) && imp.getStackSize()>1 && labelAll)
labelSlices(imp);
} else
IJ.noImage();
}
void labelSlices(ImagePlus imp) {
int slice = imp.getCurrentSlice();
for (int i=1; i<=imp.getStackSize(); i++) {
imp.setSlice(i);
drawScaleBar(imp);
}
imp.setSlice(slice);
}
boolean showDialog(ImagePlus imp) {
Roi roi = imp.getRoi();
if (roi!=null) {
Rectangle r = roi.getBounds();
roiX = r.x;
roiY = r.y;
roiWidth = r.width;
roiHeight = r.height;
location = locations[AT_SELECTION];
} else if (location.equals(locations[AT_SELECTION]))
location = locations[UPPER_RIGHT];
Calibration cal = imp.getCalibration();
ImageWindow win = imp.getWindow();
mag = (win!=null)?win.getCanvas().getMagnification():1.0;
if (mag>1.0)
mag = 1.0;
if (fontSize<(12/mag))
fontSize = (int)(12/mag);
String units = cal.getUnits();
// Div., handle Digital Micrograph unit microns
if (units.equals("micron"))
units = "µm";
double pixelWidth = cal.pixelWidth;
if (pixelWidth==0.0)
pixelWidth = 1.0;
double scale = 1.0/pixelWidth;
imageWidth = imp.getWidth()*pixelWidth;
if (roiX>0 && roiWidth>10)
barWidth = roiWidth*pixelWidth;
else if (barWidth==0.0 || barWidth>0.67*imageWidth) {
barWidth = (80.0*pixelWidth)/mag;
if (barWidth>0.67*imageWidth)
barWidth = 0.67*imageWidth;
if (barWidth>5.0)
barWidth = (int)barWidth;
}
int stackSize = imp.getStackSize();
int digits = (int)barWidth==barWidth?0:1;
if (barWidth<1.0)
digits = 2;
int percent = (int)(barWidth*100.0/imageWidth);
if (mag<1.0 && barHeightInPixels<defaultBarHeight/mag)
barHeightInPixels = (int)(defaultBarHeight/mag);
imp.getProcessor().snapshot();
if (!IJ.macroRunning()) updateScalebar();
GenericDialog gd = new BarDialog("ScaleBar Plus");
gd.addNumericField("Width in "+units+": ", barWidth, digits);
gd.addNumericField("Height in pixels: ", barHeightInPixels, 0);
gd.addNumericField("Font Size: ", fontSize, 0);
gd.addChoice("Color: ", colors, color);
// Div., add field for bkgnd color selection
gd.addChoice("Background: ", colors, bcolor);
gd.addChoice("Location: ", locations, location);
checkboxStates[0] = boldText; checkboxStates[1] = hideText;
gd.addCheckboxGroup(1, 2, checkboxLabels, checkboxStates);
if (stackSize>1)
gd.addCheckbox("Label all Slices", labelAll);
gd.showDialog();
if (gd.wasCanceled()) {
imp.getProcessor().reset();
imp.updateAndDraw();
return false;
}
barWidth = gd.getNextNumber();
barHeightInPixels = (int)gd.getNextNumber();
fontSize = (int)gd.getNextNumber();
color = gd.getNextChoice();
// Div., get bkgnd color from dialog
bcolor = gd.getNextChoice();
location = gd.getNextChoice();
boldText = gd.getNextBoolean();
hideText = gd.getNextBoolean();
if (stackSize>1)
labelAll = gd.getNextBoolean();
if (IJ.macroRunning()) updateScalebar();
return true;
}
void drawScaleBar(ImagePlus imp) {
if (!updateLocation())
return;
ImageProcessor ip = imp.getProcessor();
Undo.setup(Undo.FILTER, imp);
Color color = getColor();
// Div., set default bkgnd color
Color bcolor = getBColor();
//if (!(color==Color.white || color==Color.black)) {
// ip = ip.convertToRGB();
// imp.setProcessor(null, ip);
//}
// Div., draw bkgnd box first, based on bar width and height (and font size if hideText is not checked)
ip.setColor(bcolor);
if (!hideText)
ip.setRoi((int)(xloc-barWidthInPixels/40), (int)(yloc-barHeightInPixels), (int)(barWidthInPixels*1.1), (int)(3*barHeightInPixels+fontSize));
else
ip.setRoi((int)(xloc-imageWidth/40), (int)(yloc-barHeightInPixels), (int)(barWidthInPixels*1.1), (int)(3*barHeightInPixels));
ip.fill();
ip.resetRoi();
ip.setColor(color);
int x = xloc;
int y = yloc;
ip.setRoi(x, y, barWidthInPixels, barHeightInPixels);
ip.fill();
ip.resetRoi();
int fontType = boldText?Font.BOLD:Font.PLAIN;
// Div., change default to Serif font from SanSerif
ip.setFont(new Font("Serif", fontType, fontSize));
ip.setAntialiasedText(true);
int digits = (int)barWidth==barWidth?0:1;
//Div., reduce digits to 1 for barWidth<1
if (barWidth<1.0)
digits = 1;
// Div., handle Digital Micrograph unit microns
String units = imp.getCalibration().getUnits();
if (units.equals("microns"))
units = "µm";
// String label = IJ.d2s(barWidth, digits) + " "+ imp.getCalibration().getUnits();
// Div., change above line to work around microns
String label = IJ.d2s(barWidth, digits) + " "+ units;
x = x +(barWidthInPixels - ip.getStringWidth(label))/2;
// Div., replaced fontSize/4 with fontSize/8
y = y + barHeightInPixels + fontSize + fontSize/8;
if (!hideText)
ip.drawString(label, x, y);
imp.updateAndDraw();
}
boolean updateLocation() {
Calibration cal = imp.getCalibration();
barWidthInPixels = (int)(barWidth/cal.pixelWidth);
int width = imp.getWidth();
int height = imp.getHeight();
int fraction = 20;
int x = width - width/fraction - barWidthInPixels;
int y = 0;
if (location.equals(locations[UPPER_RIGHT]))
y = height/fraction;
else if (location.equals(locations[LOWER_RIGHT]))
y = height - height/fraction - barHeightInPixels - fontSize;
else if (location.equals(locations[UPPER_LEFT])) {
x = width/fraction;
y = height/fraction;
} else if (location.equals(locations[LOWER_LEFT])) {
x = width/fraction;
y = height - height/fraction - barHeightInPixels - fontSize;
} else {
if (roiX==-1)
return false;
x = roiX;
y = roiY;
}
xloc = x;
yloc = y;
return true;
}
Color getColor() {
// Div., changes default to black
Color c = Color.black;
if (color.equals(colors[0])) c = Color.white;
else if (color.equals(colors[2])) c = Color.lightGray;
else if (color.equals(colors[3])) c = Color.gray;
else if (color.equals(colors[4])) c = Color.darkGray;
else if (color.equals(colors[5])) c = Color.red;
else if (color.equals(colors[6])) c = Color.green;
else if (color.equals(colors[7])) c = Color.blue;
else if (color.equals(colors[8])) c = Color.yellow;
return c;
}
// Div., mimic getColor to write getBColor for bkgnd
Color getBColor() {
Color bc = Color.white;
if (bcolor.equals(colors[1])) bc = Color.black;
else if (bcolor.equals(colors[2])) bc = Color.lightGray;
else if (bcolor.equals(colors[3])) bc = Color.gray;
else if (bcolor.equals(colors[4])) bc = Color.darkGray;
else if (bcolor.equals(colors[5])) bc = Color.red;
else if (bcolor.equals(colors[6])) bc = Color.green;
else if (bcolor.equals(colors[7])) bc = Color.blue;
else if (bcolor.equals(colors[8])) bc = Color.yellow;
return bc;
}
void updateScalebar() {
updateLocation();
imp.getProcessor().reset();
drawScaleBar(imp);
}
class BarDialog extends GenericDialog {
BarDialog(String title) {
super(title);
}
public void textValueChanged(TextEvent e) {
TextField widthField = ((TextField)numberField.elementAt(0));
Double d = getValue(widthField.getText());
if (d==null)
return;
barWidth = d.doubleValue();
TextField heightField = ((TextField)numberField.elementAt(1));
d = getValue(heightField.getText());
if (d==null)
return;
barHeightInPixels = (int)d.doubleValue();
TextField fontSizeField = ((TextField)numberField.elementAt(2));
d = getValue(fontSizeField.getText());
if (d==null)
return;
int size = (int)d.doubleValue();
if (size>5)
fontSize = size;
updateScalebar();
}
public void itemStateChanged(ItemEvent e) {
Choice col = (Choice)(choice.elementAt(0));
color = col.getSelectedItem();
// Div., added handler for bkgnd color choice menu
Choice bcol = (Choice)(choice.elementAt(1));
bcolor = bcol.getSelectedItem();
Choice loc = (Choice)(choice.elementAt(2));
location = loc.getSelectedItem();
boldText = ((Checkbox)(checkbox.elementAt(0))).getState();
hideText = ((Checkbox)(checkbox.elementAt(1))).getState();
updateScalebar();
}
} //BarDialog inner class
} //ScaleBar_Plus class
-- End ScaleBar_Plus.java --
Divakar Ramachandran
Minneapolis, MN 55414, USA
---------------------------------
Here's a new way to find what you're looking for - Yahoo! Answers
Send FREE SMS to your friend's mobile from Yahoo! Messenger Version 8. Get it NOW