1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
/** This plugin, which concatenates two images or stacks, implements the
Image/Stacks/Tools/Concatenate command.
The images or stacks must have same width, height and data type. */
public class Concatenator implements PlugIn {
ImagePlus imp1, imp2;
static boolean keep;
static String title = "Concatenated Stacks";
public void run(String arg) {
if (!showDialog())
return;
ImagePlus imp3 = null;
if (imp1.isComposite() || imp1.isHyperStack()) {
ImagePlus[] images = new ImagePlus[2];
images[0] = imp1;
images[1] = imp2;
imp3 = concatenate(images, keep);
if (imp3==null)
error();
else
imp3.setTitle(title);
} else
imp3 = concatenate(imp1, imp2, keep);
if (imp3!=null) imp3.show();
}
public ImagePlus concatenate(ImagePlus imp1, ImagePlus imp2, boolean keep) {
if (imp1.getType()!=imp2.getType() || imp1.isHyperStack() || imp2.isHyperStack())
{error(); return null;}
int width = imp1.getWidth();
int height = imp1.getHeight();
if (width!=imp2.getWidth() || height!=imp2.getHeight())
{error(); return null;}
ImageStack stack1 = imp1.getStack();
ImageStack stack2 = imp2.getStack();
int size1 = stack1.getSize();
int size2 = stack2.getSize();
ImageStack stack3 = imp1.createEmptyStack();
int slice = 1;
for (int i=1; i<=size1; i++) {
ImageProcessor ip = stack1.getProcessor(slice);
String label = stack1.getSliceLabel(slice);
if (keep || imp1==imp2) {
ip = ip.duplicate();
slice++;
} else
stack1.deleteSlice(slice);
stack3.addSlice(label, ip);
}
slice = 1;
for (int i=1; i<=size2; i++) {
ImageProcessor ip = stack2.getProcessor(slice);
String label = stack2.getSliceLabel(slice);
if (keep || imp1==imp2) {
ip = ip.duplicate();
slice++;
} else
stack2.deleteSlice(slice);
stack3.addSlice(label, ip);
}
ImagePlus imp3 = new ImagePlus(title, stack3);
imp3.setCalibration(imp1.getCalibration());
if (!keep) {
imp1.changes = false;
imp1.close();
if (imp1!=imp2) {
imp2.changes = false;
imp2.close();
}
}
return imp3;
}
public ImagePlus concatenate(ImagePlus[] images, boolean keepSourceImages) {
int n = images.length;
int width = images[0].getWidth();
int height = images[0].getHeight();
int bitDepth = images[0].getBitDepth();
int channels = images[0].getNChannels();
int slices = images[0].getNSlices();
int frames = images[0].getNFrames();
boolean concatSlices = slices>1 && frames==1;
for (int i=1; i<n; i++) {
if (images[i].getNFrames()>1) concatSlices = false;
if (images[i].getWidth()!=width
|| images[i].getHeight()!=height
|| images[i].getBitDepth()!=bitDepth
|| images[i].getNChannels()!=channels
|| (!concatSlices && images[i].getNSlices()!=slices))
return null;
}
ImageStack stack2 = new ImageStack(width, height);
int slices2=0, frames2=0;
for (int i=0;i<n;i++) {
ImageStack stack = images[i].getStack();
slices = images[i].getNSlices();
if (concatSlices) {
slices = images[i].getNSlices();
slices2 += slices;
frames2 = frames;
} else {
frames = images[i].getNFrames();
frames2 += frames;
slices2 = slices;
}
for (int f=1; f<=frames; f++) {
for (int s=1; s<=slices; s++) {
for (int c=1; c<=channels; c++) {
int index = (f-1)*channels*s + (s-1)*channels + c;
ImageProcessor ip = stack.getProcessor(index);
if (keepSourceImages)
ip = ip.duplicate();
String label = stack.getSliceLabel(index);
stack2.addSlice(label, ip);
}
}
}
}
ImagePlus imp2 = new ImagePlus("Concatenated Images", stack2);
imp2.setDimensions(channels, slices2, frames2);
if (channels>1) {
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 (!keepSourceImages) {
for (int i=0; i<n; i++) {
images[i].changes = false;
images[i].close();
}
}
return imp2;
}
int getStackIndex(int channel, int slice, int frame, int nChannels, int nSlices, int nFrames) {
return (frame-1)*nChannels*nSlices + (slice-1)*nChannels + channel;
}
boolean showDialog() {
int[] wList = WindowManager.getIDList();
if (wList==null) {
IJ.noImage();
return false;
}
String[] titles = new String[wList.length];
for (int i=0; i<wList.length; i++) {
ImagePlus imp = WindowManager.getImage(wList[i]);
titles[i] = imp!=null?imp.getTitle():"";
}
GenericDialog gd = new GenericDialog("Concatenator");
gd.addChoice("Stack1:", titles, titles[0]);
gd.addChoice("Stack2:", titles, wList.length>1?titles[1]:titles[0]);
gd.addStringField("Title:", title, 16);
gd.addCheckbox("Keep Source Stacks", keep);
gd.showDialog();
if (gd.wasCanceled())
return false;
int[] index = new int[3];
int index1 = gd.getNextChoiceIndex();
int index2 = gd.getNextChoiceIndex();
title = gd.getNextString();
keep = gd.getNextBoolean();
imp1 = WindowManager.getImage(wList[index1]);
imp2 = WindowManager.getImage(wList[index2]);
return true;
}
void error() {
IJ.showMessage("Concatenator", "This command requires two images with\n"+
"the same dimesions and data type.");
}
}
|