ScaleBar modification

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

ScaleBar modification

Divakar Ramachandran
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