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.