|
RGBStackMerge |
|
package ij.plugin; import ij.*; import ij.process.*; import ij.gui.*; public class RGBStackMerge implements PlugIn { private ImagePlus imp; private byte[] blank; /** Merges one, two or three 8-bit or RGB stacks into a single RGB stack. */ public void run(String arg) { imp = WindowManager.getCurrentImage(); mergeStacks(); } /** Combines three grayscale stacks into one RGB stack. */ public void mergeStacks() { int[] wList = WindowManager.getIDList(); if (wList==null) { IJ.error("No images are open."); return; } String[] titles = new String[wList.length+1]; for (int i=0; i<wList.length; i++) { ImagePlus imp = WindowManager.getImage(wList[i]); titles[i] = imp!=null?imp.getTitle():""; } String none = "*None*"; titles[wList.length] = none; GenericDialog gd = new GenericDialog("RGB Merge"); gd.addChoice("Red:", titles, titles[0]); gd.addChoice("Green:", titles, titles[1]); String title3 = titles.length>2?titles[2]:none; gd.addChoice("Blue:", titles, title3); gd.addCheckbox("Keep source images", false); gd.showDialog(); if (gd.wasCanceled()) return; int[] index = new int[3]; index[0] = gd.getNextChoiceIndex(); index[1] = gd.getNextChoiceIndex(); index[2] = gd.getNextChoiceIndex(); boolean keep = gd.getNextBoolean(); ImagePlus[] image = new ImagePlus[3]; int stackSize = 0; int width = 0; int height = 0; for (int i=0; i<3; i++) { if (index[i]<wList.length) { image[i] = WindowManager.getImage(wList[index[i]]); width = image[i].getWidth(); height = image[i].getHeight(); stackSize = image[i].getStackSize(); } } if (width==0) { IJ.error("There must be at least one source image or stack."); return; } for (int i=0; i<3; i++) { ImagePlus img = image[i]; if (img!=null) { if (img.getStackSize()!=stackSize) { IJ.error("The source stacks must all have the same number of slices."); return; } //if (!(img.getType()==ImagePlus.GRAY8||img.getType()==ImagePlus.COLOR_RGB)) { // IJ.error("The source stacks must be 8-bit grayscale or RGB."); // return; //} if (img.getWidth()!=width || image[i].getHeight()!=height) { IJ.error("The source images or stacks must have the same width and height."); return; } } } ImageStack red = image[0]!=null?image[0].getStack():null; ImageStack green = image[1]!=null?image[1].getStack():null; ImageStack blue = image[2]!=null?image[2].getStack():null; ImageStack rgb = mergeStacks(width, height, stackSize, red, green, blue, keep); if (!keep) for (int i=0; i<3; i++) { if (image[i]!=null) { image[i].changes = false; image[i].close(); } } ImagePlus imp2 = new ImagePlus("RGB", rgb); if (image[0]!=null) imp2.setCalibration(image[0].getCalibration()); imp2.show(); } public ImageStack mergeStacks(int w, int h, int d, ImageStack red, ImageStack green, ImageStack blue, boolean keep) { ImageStack rgb = new ImageStack(w, h); int inc = d/10; if (inc<1) inc = 1; ColorProcessor cp; int slice = 1; blank = new byte[w*h]; byte[] redPixels, greenPixels, bluePixels; boolean invertedRed = red!=null?red.getProcessor(1).isInvertedLut():false; boolean invertedGreen = green!=null?green.getProcessor(1).isInvertedLut():false; boolean invertedBlue = blue!=null?blue.getProcessor(1).isInvertedLut():false; try { for (int i=1; i<=d; i++) { cp = new ColorProcessor(w, h); redPixels = getPixels(red, slice, 0); greenPixels = getPixels(green, slice, 1); bluePixels = getPixels(blue, slice, 2); if (invertedRed) redPixels = invert(redPixels); if (invertedGreen) greenPixels = invert(greenPixels); if (invertedBlue) bluePixels = invert(bluePixels); cp.setRGB(redPixels, greenPixels, bluePixels); if (keep) { slice++; } else { if (red!=null) red.deleteSlice(1); if (green!=null &&green!=red) green.deleteSlice(1); if (blue!=null&&blue!=red && blue!=green) blue.deleteSlice(1); } rgb.addSlice(null, cp); if ((i%inc) == 0) IJ.showProgress((double)i/d); } IJ.showProgress(1.0); } catch(OutOfMemoryError o) { IJ.outOfMemory("Merge Stacks"); IJ.showProgress(1.0); } return rgb; } byte[] getPixels(ImageStack stack, int slice, int color) { if (stack==null) return blank; Object pixels = stack.getPixels(slice); if (!(pixels instanceof int[])) { if (pixels instanceof byte[]) return (byte[])pixels; else { ImageProcessor ip = stack.getProcessor(slice); ip = ip.convertToByte(true); return (byte[])ip.getPixels(); } } else { //RGB byte[] r,g,b; int size = stack.getWidth()*stack.getHeight(); r = new byte[size]; g = new byte[size]; b = new byte[size]; ColorProcessor cp = (ColorProcessor)stack.getProcessor(slice); cp.getRGB(r, g, b); switch (color) { case 0: return r; case 1: return g; case 2: return b; } } return null; } byte[] invert(byte[] pixels) { byte[] pixels2 = new byte[pixels.length]; System.arraycopy(pixels, 0, pixels2, 0, pixels.length); for (int i=0; i<pixels2.length; i++) pixels2[i] = (byte)(255-pixels2[i]&255); return pixels2; } }
|
RGBStackMerge |
|