package ij.plugin;
import ij.*;
import ij.macro.Interpreter;
import ij.process.*; 
import ij.gui.*;
import java.awt.*;
import ij.measure.*;
import ij.plugin.filter.*;
import ij.plugin.frame.Recorder;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import java.awt.image.ColorModel;

/** This plugin, which concatenates two or more images or stacks,
 *	implements the Image/Stacks/Tools/Concatenate command.
 *	Has the option of viewing the concatenated stack as a 4D image.
 *	@author Jon Jackson j.jackson # ucl.ac.uk
 */
public class Concatenator implements PlugIn, ItemListener{
	public String pluginName =	"Concatenator";
	public int maxEntries = 18;	 // limit number of entries to fit on screen
	private static boolean all_option = false;
	private boolean keep = false;
	private static boolean keep_option = false;
	private boolean batch = false;
	private boolean macro = false;
	private boolean im4D = true;
	private static boolean im4D_option = true;
	private String[] imageTitles;
	private ImagePlus[] images;
	private Vector choices;
	private Checkbox allWindows;
	private final String none = "-- None --";
	private String newtitle = "Untitled";
	private ImagePlus newImp;
	private int stackSize;
	private double min = 0, max = Float.MAX_VALUE;
	private int maxWidth, maxHeight;
	private boolean showingDialog;

	
	/** Optional string argument sets the name dialog boxes if called from another plugin. */
	public void run(String arg) {
		macro = !arg.equals("");
		if (!showDialog())
			return;
		newImp = concatenate(images, keep);
		if (newImp!=null)
			newImp.show();
	}
	
	/** Displays a dialog requiring user to choose images and
		returns ImagePlus of concatenated images. */
	public ImagePlus run() {
		if (!showDialog())
			return null;
		newImp = createHypervol();
		return newImp;
	}
	
	/** Concatenates two images, stacks or hyperstacks. */
	public static ImagePlus run(ImagePlus img1, ImagePlus img2) {
		ImagePlus[] images = new ImagePlus[2];
		images[0]=img1; images[1]=img2;
		return (new Concatenator()).concatenate(images, false);
	}

	/** Concatenates three images, stacks or hyperstacks. */
	public static ImagePlus run(ImagePlus img1, ImagePlus img2, ImagePlus img3) {
		ImagePlus[] images = new ImagePlus[3];
		images[0]=img1; images[1]=img2;  images[2]=img3;
		return (new Concatenator()).concatenate(images, false);
	}

	/** Concatenates four images, stacks or hyperstacks. */
	public static ImagePlus run(ImagePlus img1, ImagePlus img2, ImagePlus img3, ImagePlus img4) {
		ImagePlus[] images = new ImagePlus[4];
		images[0]=img1; images[1]=img2;  images[2]=img3; images[2]=img4;
		return (new Concatenator()).concatenate(images, false);
	}

	/** Concatenates five images, stacks or hyperstacks. */
	public static ImagePlus run(ImagePlus img1, ImagePlus img2, ImagePlus img3, ImagePlus img4, ImagePlus img5) {
		ImagePlus[] images = new ImagePlus[5];
		images[0]=img1; images[1]=img2;  images[2]=img3; images[2]=img4; images[5]=img5;
		return (new Concatenator()).concatenate(images, false);
	}

	/** Concatenates two or more images, stacks or hyperstacks.
	 * @param images Array of source images
	 * @return Returns the concatenated images as an ImagePlus
	*/
	public static ImagePlus run(ImagePlus[] images) {
		return  (new Concatenator()).concatenate(images, false);
	}

	/*
	// Why does this not work with Java 6?
	public static ImagePlus run(ImagePlus... args) {
		return (new Concatenator()).concatenate(args, false);
	}
	*/

	/** Concatenates two or more images or stacks. */
	public ImagePlus concatenate(ImagePlus[] ims, boolean keepIms) {
		images = ims;
		imageTitles = new String[ims.length];
		for (int i = 0; i < ims.length; i++) {
			if (ims[i] != null) {
				imageTitles[i] = ims[i].getTitle();
			} else {
				IJ.error(pluginName, "Null ImagePlus passed to concatenate(...) method");
				return null;
			}
		}
		keep = keepIms;
		batch = true;
		ImagePlus imp0 = images[0];
		if (imp0.isComposite() || imp0.getNChannels()>1)
			newImp = concatenateHyperstacks(images, newtitle, keep);
		else
			newImp = createHypervol();
		if (Recorder.scriptMode()) {
			String args = "imp1";
			for (int i=1; i1 && frames==1;
		boolean keepCalibration = true;
		Calibration cal = images[0].getCalibration();
		maxWidth = width;
		maxHeight = height;
		
		for (int i=1; i1)
				concatSlices = false;
			if (images[i].getBitDepth()!=bitDepth
			|| images[i].getNChannels()!=channels
			|| (!concatSlices && images[i].getNSlices()!=slices)) {
				IJ.error(pluginName, "Images do not all have the same dimensions or type");
				return null;
			}
			Calibration cal2 = images[i].getCalibration();
			if (cal2.pixelWidth!=cal.pixelWidth 
			|| cal2.pixelHeight!=cal.pixelHeight 
			|| cal2.pixelDepth != cal.pixelDepth)
				keepCalibration = false;
			if (images[i].getWidth()>maxWidth)
				maxWidth = images[i].getWidth();
			if (images[i].getHeight()>maxHeight)
				maxHeight = images[i].getHeight();
		}
		ImageStack stack2 = new ImageStack(maxWidth, maxHeight);
		int slices2=0, frames2=0;
		for (int i=0;i1) {
			int mode = 0;
			if (images[0].isComposite())
				mode = ((CompositeImage)images[0]).getMode();
			imp2 = new CompositeImage(imp2, mode);
			((CompositeImage)imp2).copyLuts(images[0]);
		}
		if (channels>1 && frames2>1)
			imp2.setOpenAsHyperStack(true);
		if (keepCalibration)
			imp2.setCalibration(cal);
		if (!keep) {
			for (int i=0; i= nImages) break; // reached the 'none' string or handled all images (in case of all_windows)
			if (! titles[index].equals("")) {
				tmpStrArr[count] = titles[index];
				tmpImpArr[count] = WindowManager.getImage(wList[index]);
				count++;
			}
		}
		if (count<2) {
			IJ.error(pluginName, "Please select at least 2 images");
			return false;
		}
		
		imageTitles = new String[count];
		images = new ImagePlus[count];
		System.arraycopy(tmpStrArr, 0, imageTitles, 0, count);
		System.arraycopy(tmpImpArr, 0, images, 0, count);
		return true;
	}
	
	// test if this imageplus appears again in the list
	boolean isDuplicated(ImagePlus imp, int index) {
		int length = images.length;
		if (index >= length - 1) return false;
		for (int i = index + 1; i < length; i++) {
			if (imp == images[i]) return true;
		}
		return false;
	}
	
	public void itemStateChanged(ItemEvent ie) {
		Choice c;
		if (ie.getSource() == allWindows) { // User selected / unselected 'all windows' button
			int count = 0;
			if (allWindows.getState()) {
				for (Enumeration e = choices.elements() ; e.hasMoreElements() ;) {
					c = (Choice)e.nextElement();
					c.select(count++);
					c.setEnabled(false);
				}
			} else {
				for (Enumeration e = choices.elements() ; e.hasMoreElements() ;) {
					c = (Choice)e.nextElement();
					c.setEnabled(true);
				}
			}
		} else { // User image selection triggered event
			boolean foundNone = false;
			// All image choices after an occurance of 'none' are reset to 'none'
			for (Enumeration e = choices.elements() ; e.hasMoreElements() ;) {
				c = (Choice)e.nextElement();
				if (! foundNone) {
					c.setEnabled(true);
					if (c.getSelectedItem().equals(none)) foundNone = true;
				} else { // a previous choice was 'none'
					c.select(none);
					c.setEnabled(false);
				}
			}
		}
	}
	
	public void setIm5D(boolean bool) {
		im4D_option = bool;
		im4D = bool;
	}
	
	private void findMaxDimensions(ImagePlus[] images) {
		boolean first = true;
		ImagePlus currentImp = null;
		int dataType = 0;
		maxWidth = maxHeight = 0;
		for (int i = 0; i < images.length; i++) {
			if (images[i] != null) {
				currentImp = images[i];
				if (first) {
					dataType = currentImp.getType();
					first = false;
				}
				if (currentImp.getType() != dataType)
					continue;
				if (currentImp.getWidth()>maxWidth)
					maxWidth = currentImp.getWidth();
				if (currentImp.getHeight()>maxHeight)
					maxHeight = currentImp.getHeight();
			}
		}
	}
	
}

 

Ads help maintain this website.