package edu.mbl.jif.imagej; import java.util.ArrayList; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferDouble; import java.awt.image.DataBufferFloat; import java.awt.image.DataBufferInt; import java.awt.image.DataBufferShort; import java.awt.image.DataBufferUShort; import java.awt.image.IndexColorModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import ij.ImagePlus; import ij.ImageStack; import ij.measure.Calibration; import ij.process.ByteProcessor; import ij.process.ColorProcessor; import ij.process.FloatProcessor; import ij.process.ImageProcessor; import ij.process.ImageStatistics; import ij.process.ShortProcessor; //import edu.mbl.jif.imaging.ImgInfoDumper; //import psj.PolStack.PolStack; import java.lang.reflect.InvocationTargetException; import javax.swing.SwingUtilities; import org.dart.imagej.IJClient; import org.dart.imagej.IJClientFactory; public class IJMaker { public static void main(String[] args) { invokeImageJ(); } // === Open ImageJ ========================================================= public static void invokeImageJ() { dispatchToEDT(new Runnable() { public void run() { openImageJ(); } }); } public static void openImageJ() { IJClient ijClient = IJClientFactory.getIJClient(false); // ImageJ ij = IJ.getInstance(); // if (ij == null || (ij != null && !ij.isShowing())) { // if (IJ.isMacOSX()) { // System.setProperty("com.apple.mrj.application.growbox.intrudes", // "true"); // ij = new ImageJ(null); // System.setProperty("com.apple.mrj.application.growbox.intrudes", // "false"); // } else { // ij = new ImageJ(null); // } // } // if(ij != null) { // ij.setVisible(true); // } } public static void dispatchToEDT(Runnable runnable) { if (!SwingUtilities.isEventDispatchThread()) { try { SwingUtilities.invokeAndWait(runnable); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } else { runnable.run(); } } // Make ImageJ stack from array of BufferedImages public static ImagePlus makeStack(String name, BufferedImage[] rImage) { ImagePlus imp = null; if (name == null) { name = "None"; } if (rImage.length >= 1) { ImageStack stack = new ImageStack(rImage[0].getWidth(), rImage[0].getHeight()); for (int i = 0; i < (rImage.length); i++) { DataBuffer dBuff = rImage[i].getData().getDataBuffer(); ColorModel cm = rImage[i].getColorModel(); try { ImageProcessor ip = createProcessor(rImage[i].getWidth(), rImage[i].getHeight(), dBuff, cm); stack.addSlice(String.valueOf(i - 1), ip); } catch (Exception ex) { ex.printStackTrace(); } //stack.addSlice(); } if (stack == null) { return null; } if (stack.getSize() == 0) { return null; } imp = new ImagePlus(name, stack); } else { // single image imp = new ImagePlus(name, (Image) rImage[0]); } imp.show(); // setResolution(fi, imp); return imp; } // Make ImageJ stack from array of RenderedImages public static ImagePlus makeStack(String name, RenderedImage[] rImage) { Object pixels = null; ImagePlus imp = null; if (name == null) { name = "None"; } if (rImage.length > 1) { ImageStack stack = new ImageStack(rImage[0].getWidth(), rImage[0].getHeight()); for (int i = 0; i < (rImage.length); i++) { DataBuffer dBuff = rImage[i].getData().getDataBuffer(); ColorModel cm = rImage[i].getColorModel(); try { ImageProcessor ip = createProcessor(rImage[i].getWidth(), rImage[i].getHeight(), dBuff, cm); stack.addSlice(String.valueOf(i - 1), ip); } catch (Exception ex) { ex.printStackTrace(); } //stack.addSlice(); } if (stack == null) { return null; } if (stack.getSize() == 0) { return null; } imp = new ImagePlus(name, stack); } else { // single image imp = new ImagePlus(name, (Image) rImage[0]); } imp.show(); // setResolution(fi, imp); return imp; } // //--------------------------------------------------------------------- public static ImagePlus makeImagePlus(String name, java.awt.Image awtImage) { ImagePlus iPlus = new ImagePlus(name, awtImage); ByteProcessor ip = (ByteProcessor) iPlus.getProcessor(); return iPlus; // ImagePlus createBtyeImage(title, w, h, slices, fill) } // //--------------------------------------------------------------------------- public static double[] getLinePixels(String name, java.awt.Image awtImage, Rectangle roi) { ImagePlus iPlus = new ImagePlus(name, awtImage); ByteProcessor ip = (ByteProcessor) iPlus.getProcessor(); return ip.getLine((double) roi.getX(), (double) (roi.getX() + roi.getWidth()), (double) roi.getY(), (double) (roi.getY() + roi.getHeight())); } //=========================================================================== /** * Create an ImageProcessor object from a DataBuffer. * * @param w Image width. * @param h Image height. * @param buffer Data buffer. * @param cm Color model. * @return Image processor object. * @exception Exception If data buffer is in unknown format. * From ijImageIO */ public static ImageProcessor createProcessor(int w, int h, DataBuffer buffer, ColorModel cm) throws Exception { if (buffer.getOffset() != 0) { throw new Exception("Expecting BufferData with no offset."); } switch (buffer.getDataType()) { case DataBuffer.TYPE_BYTE: return new ByteProcessor(w, h, ((DataBufferByte) buffer).getData(), cm); case DataBuffer.TYPE_USHORT: return new ShortProcessor(w, h, ((DataBufferUShort) buffer).getData(), cm); case DataBuffer.TYPE_SHORT: short[] pixels = ((DataBufferShort) buffer).getData(); for (int i = 0; i < pixels.length; ++i) { pixels[i] = (short) (pixels[i] + 32768); } return new ShortProcessor(w, h, pixels, cm); case DataBuffer.TYPE_INT: return new FloatProcessor(w, h, ((DataBufferInt) buffer).getData()); case DataBuffer.TYPE_FLOAT: { DataBufferFloat dbFloat = (DataBufferFloat) buffer; return new FloatProcessor(w, h, dbFloat.getData(), cm); } case DataBuffer.TYPE_DOUBLE: return new FloatProcessor(w, h, ((DataBufferDouble) buffer).getData()); case DataBuffer.TYPE_UNDEFINED: throw new Exception("Pixel type is undefined."); default: throw new Exception("Unrecognized DataBuffer data type"); } } //=========================================================================== public static ImagePlus[] makeImagePlusArray( BufferedImage[] imageArray, String title) throws Exception { // Get number of sub images int nbPages = imageArray.length; if (nbPages < 1) { throw new Exception("Image decoding problem. " + "Image file has less then 1 page. Nothing to decode."); } // Iterate through pages ArrayList imageList = new ArrayList(); for (int i = 0; i < nbPages; ++i) { imageList.add(create(imageArray[i].getRaster(), null, "Something")); } ImagePlus[] images = (ImagePlus[]) imageList.toArray( new ImagePlus[imageList.size()]); if (nbPages == 1) { // Do not use page numbers in image name images[0].setTitle(title); } else { // Attempt to combine images into a single stack. ImagePlus im = combineImages(images); if (im != null) { im.setTitle(title); images = new ImagePlus[1]; images[0] = im; } } return images; } /** * Attempt to combine images into a single stack. Images can be combined into * a stack if all of them are single slice images of the same type and * dimensions. * @param images Array of images. * @return Input images combined into a stack. Return null if images * cannot be combined. */ public static ImagePlus combineImages(ImagePlus[] images) { if (images == null || images.length <= 1) { return null; } if (images[0].getStackSize() != 1) { return null; } int fileType = images[0].getFileInfo().fileType; int w = images[0].getWidth(); int h = images[0].getHeight(); ImageStack stack = images[0].getStack(); for (int i = 1; i < images.length; ++i) { ImagePlus im = images[i]; if (im.getStackSize() != 1) { return null; } if (fileType == im.getFileInfo().fileType && w == im.getWidth() && h == im.getHeight()) { stack.addSlice(null, im.getProcessor().getPixels()); } else { return null; } } images[0].setStack(images[0].getTitle(), stack); return images[0]; } /** * Create instance of ImagePlus from WritableRaster r and ColorModel cm. * * @param r Raster containing pixel data. * @param cm Image color model (can be null). * @return ImagePlus object created from WritableRaster r and * ColorModel cm * @exception Exception when enable to create ImagePlus. */ public static ImagePlus create(WritableRaster r, ColorModel cm, String title) throws Exception { DataBuffer db = r.getDataBuffer(); int numBanks = db.getNumBanks(); if (numBanks > 1 && cm == null) { throw new Exception("Don't know what to do with image with no " + "color model and multiple banks."); } SampleModel sm = r.getSampleModel(); int dbType = db.getDataType(); if (numBanks > 1 || sm.getNumBands() > 1 ) { // If image has multiple banks or multiple color components, assume that it // is a color image and relay on AWT for proper decoding. BufferedImage bi = new BufferedImage(cm, r, false, null); return new ImagePlus(null, new ColorProcessor((Image) bi)); } else if (sm.getSampleSize(0) < 8) { // Temporary fix for less then 8 bit images BufferedImage bi = new BufferedImage(cm, r, false, null); return new ImagePlus(null, new ByteProcessor((Image) bi)); } else { if (!(cm instanceof IndexColorModel)) { // Image/J (as of version 1.26r) can not properly deal with non color // images and ColorModel that is not an instance of IndexedColorModel. cm = null; } ImageProcessor ip = createProcessor(r.getWidth(), r.getHeight(), r.getDataBuffer(), cm); ImagePlus im = new ImagePlus(title, ip); // Add calibration function for 'short' pixels if (db.getDataType() == DataBuffer.TYPE_SHORT) { Calibration cal = new Calibration(im); double[] coeff = new double[2]; coeff[0] = -32768.0; coeff[1] = 1.0; cal.setFunction(Calibration.STRAIGHT_LINE, coeff, "gray value"); im.setCalibration(cal); } else if (cm == null) { Calibration cal = im.getCalibration(); im.setCalibration(null); ImageStatistics stats = im.getStatistics(); im.setCalibration(cal); ip.setMinAndMax(stats.min, stats.max); im.updateImage(); } return im; } } public static void test() { /** @todo test with short and float */ // BufferedImage bi = edu.mbl.jif.imaging.ImageFactoryGrayScale.testImageByte(); // System.out.println(ImgInfoDumper.dump(bi)); // ImagePlus iPlus = new ImagePlus("NewImagePlus", bi); // makes an RGB // iPlus.show(); // try { // ImagePlus iPlus2 = create(bi.getRaster(), bi.getColorModel(), "create"); // iPlus2.show(); // } catch (Exception ex) { // ex.printStackTrace(); } // // int n = 6; // BufferedImage[] biArray = new BufferedImage[n]; // for (int i = 0; i < n; i++) { // biArray[i] = edu.mbl.jif.imaging.ImageFactoryGrayScale.testImageByte(); // } // ImagePlus[] iPlusArray = new ImagePlus[n]; // for (int i = 0; i < n; i++) { // try { // iPlusArray[i] = create(biArray[i].getRaster(), biArray[i].getColorModel(), // "slice " + String.valueOf(i)); // iPlusArray[i].show(); // } catch (Exception ex) { // ex.printStackTrace(); } // } // // Combine the images into a stack // ImagePlus iPlusStack = combineImages(iPlusArray); // iPlusStack.show(); } } class UnsupportedImageModelException extends Exception { public UnsupportedImageModelException(String message) { super(message); } }