/************************************** * Gel_converter.java class to invert b&w images, reduce the size and * fix brightness/contrast for printing. * * @author Jimmy Burnette, June 6, 2002 Finished June 14, 2002 * @version 1.0 * Please use, hack, and re-distribute for free. May not be used in fee based programs. * * Partially based on Inverter_.java plugin, ContrastAdjuster.java, and Scaler.java * from Wayne Rasband * -- converts RGB to 8 Bit gray * -- inverts * -- AutoAdjusts brightness and contrast * -- despeckle * -- scale (user determines scaling factor) * -- user chooses image in new window or not. * */ import ij.*; import ij.plugin.filter.PlugInFilter; import ij.plugin.*; import ij.process.*; import java.awt.*; import ij.measure.*; import ij.process.*; import ij.gui.*; public class Gel_converter implements PlugInFilter { static final int AUTO_THRESHOLD = 5000; double scaleWidth = 0.0; double scaleHeight = 0.0; public int setup(String arg, ImagePlus imp) { if (arg.equals("about")) {showAbout(); return DONE;} return DOES_ALL; } private ImagePlus imp; public void run(ImageProcessor ip) { imp = WindowManager.getCurrentImage(); if (ip instanceof ByteProcessor) { invert8BitImage(ip); IJ.showStatus ("Image inverted"); autoAdjust(ip, imp); IJ.showStatus ("Brightness/Contrast adjusted"); IJ.showStatus ("Despeckling . . . "); ip.medianFilter(); //despeckle filter. IJ.showStatus ("Despeckled"); scale (ip, imp); IJ.showMessage ("Conversion complete."); } else { ImageConverter ic = new ImageConverter (imp); ic.convertToGray8(); imp.repaintWindow(); ip = ip.convertToByte(true); invert8BitImage(ip); IJ.showStatus ("Image inverted"); autoAdjust(ip, imp); IJ.showStatus ("Brightness/Contrast adjusted"); IJ.showStatus ("Despeckling . . . "); ip.medianFilter(); //despeckle filter. IJ.showStatus ("Despeckled"); scale (ip, imp); IJ.showMessage ("Conversion complete."); } } //from Inverter_.java public void invert8BitImage(ImageProcessor ip) { byte[] pixels = (byte[])ip.getPixels(); int width = ip.getWidth(); Rectangle r = ip.getRoi(); int offset, i; for (int y=r.y; y<(r.y+r.height); y++) { offset = y*width; for (int x=r.x; x<(r.x+r.width); x++) { i = offset + x; pixels[i] = (byte)(255-pixels[i]); } } imp.setProcessor ("Converted", ip); imp.repaintWindow(); } public void showAbout() { IJ.showMessage ("About Gel Converter . . .", "Gel Conveter takes a RGB image and converts it to 8 grays, \n" + "inverts the image, auto adjusts the brightness/contrast, \n" + "despeckles, and scales it, perfect for printing. \n" + "Gel Converter was written to go along with images taken \n" + "from a Kodak DC290 camera." ); } /** Get the scale factor and show scaled image in seperate window. Hacked from *ij.plugin.filter.Scaler */ public void scale (ImageProcessor ip, ImagePlus imp) { boolean newWindow = true; GenericDialog gd = new GenericDialog("Set scale factor", IJ.getInstance()); gd.addMessage ("Enter scale factor (5-100%). 20% works well for printing."); gd.addNumericField ("Width: ", 20, 1); gd.addNumericField ("Height: ", 20, 1); gd.addMessage ("Select CANCEL for no scale."); gd.addCheckbox ("Show in new window?", newWindow); gd.showDialog(); if (gd.wasCanceled()) { //no scale IJ.showStatus ("Scale cancelled"); return; } scaleWidth = (gd.getNextNumber () / 100); scaleHeight = (gd.getNextNumber () / 100); newWindow = gd.getNextBoolean(); if (!newWindow) { ip.scale(scaleWidth, scaleHeight); imp.setProcessor ("Converted", ip); imp.repaintWindow(); } else { ImagePlus ipl2 = imp.createImagePlus(); int newWidth = (int)(ip.getWidth() * scaleWidth); int newHeight = (int)(ip.getHeight() * scaleHeight); ipl2.setProcessor("Scaled", ip.resize(newWidth, newHeight)); ipl2.show(); ipl2.trimProcessor(); imp.trimProcessor(); ipl2.changes = true; //force user to decide to save or not } IJ.showStatus ("Scaled"); } /** *autoAdjust() hacked from IJ.pluginFrame.ContrastAdjuster from main IJ package. * */ void autoAdjust (ImageProcessor ip, ImagePlus imp) { boolean RGBImage = false; int autoThreshold = 0; double min,max; if (RGBImage) ip.reset(); Calibration cal = imp.getCalibration(); imp.setCalibration(null); ImageStatistics stats = imp.getStatistics(); // get uncalibrated stats imp.setCalibration(cal); int[] histogram = stats.histogram; if (autoThreshold<10) autoThreshold = AUTO_THRESHOLD; else autoThreshold /= 2; int threshold = stats.pixelCount/autoThreshold; int i = -1; boolean found = false; do { i++; found = histogram[i] > threshold; } while (!found && i<255); int hmin = i; i = 256; do { i--; found = histogram[i] > threshold; } while (!found && i>0); int hmax = i; if (hmax>=hmin) { imp.killRoi(); min = stats.histMin+hmin*stats.binSize; max = stats.histMin+hmax*stats.binSize; if (min==max) {min=stats.min; max=stats.max;} ip.setMinAndMax(min, max); } else { //reset(imp, ip); return; } Roi roi = imp.getRoi(); if (roi!=null) { int[] mask = roi.getMask(); if (mask!=null) ip.reset(mask); } imp.setProcessor ("Converted", ip); imp.repaintWindow(); } } //closes class Gel_converter