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
|
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
/**
This plugin implements the Image/Stacks/Combine command.
It combines two stacks (w1xh1xd1 and w2xh2xd2) to create a new
w1+w2 x max(h1,h2) x max(d1,d2) stack. For example, a 256x256x40
and a 256x256x30 stack would be combined into one 512x256x40 stack.
If "Vertical" is checked, create a new max(w1+w2) x (h1+h2) x max(d1,d2) stack.
Unused areas in the combined stack are filled with the background color.
*/
public class StackCombiner implements PlugIn {
ImagePlus imp1;
ImagePlus imp2;
static boolean vertical;
public void run(String arg) {
if (!showDialog())
return;
if (imp1.getBitDepth()!=imp2.getBitDepth()) {
error();
return;
}
int[] dim1 = imp1.getDimensions();
int[] dim2 = imp2.getDimensions();
if (imp1.isHyperStack() || imp2.isHyperStack()) {
if (dim1[2]!=dim2[2] || dim1[3]!=dim2[3] || dim1[4]!=dim2[4]) {
IJ.error("StackCombiner", "Hyperstacks must have identical CZT dimensions");
return;
}
}
ImageStack stack1 = imp1.getStack();
ImageStack stack2 = imp2.getStack();
ImageStack stack3 = vertical?combineVertically(stack1, stack2):combineHorizontally(stack1, stack2);
imp1.changes = false;
imp1.close();
imp2.changes = false;
imp2.close();
ImagePlus imp3 = imp1.createImagePlus();
imp3.setStack(stack3);
if (imp1.isHyperStack())
imp3.setDimensions(dim1[2],dim1[3],dim1[4]);
if (imp1.isComposite()) {
imp3 = new CompositeImage(imp3, imp1.getCompositeMode());
imp3.setDimensions(dim1[2],dim1[3],dim1[4]);
}
imp3.setTitle("Combined Stacks");
imp3.show();
}
public ImageStack combineHorizontally(ImageStack stack1, ImageStack stack2) {
int d1 = stack1.getSize();
int d2 = stack2.getSize();
int d3 = Math.max(d1, d2);
int w1 = stack1.getWidth();
int h1 = stack1.getHeight();
int w2 = stack2.getWidth();
int h2 = stack2.getHeight();
int w3 = w1 + w2;
int h3 = Math.max(h1, h2);
ImageStack stack3 = new ImageStack(w3, h3, stack1.getColorModel());
ImageProcessor ip = stack1.getProcessor(1);
ImageProcessor ip1, ip2, ip3;
Color background = Toolbar.getBackgroundColor();
for (int i=1; i<=d3; i++) {
IJ.showProgress((double)i/d3);
ip3 = ip.createProcessor(w3, h3);
if (h1!=h2) {
ip3.setColor(background);
ip3.fill();
}
if (i<=d1) {
ip3.insert(stack1.getProcessor(1),0,0);
if (stack2!=stack1)
stack1.deleteSlice(1);
}
if (i<=d2) {
ip3.insert(stack2.getProcessor(1),w1,0);
stack2.deleteSlice(1);
}
stack3.addSlice(null, ip3);
}
return stack3;
}
public ImageStack combineVertically(ImageStack stack1, ImageStack stack2) {
int d1 = stack1.getSize();
int d2 = stack2.getSize();
int d3 = Math.max(d1, d2);
int w1 = stack1.getWidth();
int h1 = stack1.getHeight();
int w2 = stack2.getWidth();
int h2 = stack2.getHeight();
int w3 = Math.max(w1, w2);
int h3 = h1 + h2;
ImageStack stack3 = new ImageStack(w3, h3, stack1.getColorModel());
ImageProcessor ip = stack1.getProcessor(1);
ImageProcessor ip1, ip2, ip3;
Color background = Toolbar.getBackgroundColor();
for (int i=1; i<=d3; i++) {
IJ.showProgress((double)i/d3);
ip3 = ip.createProcessor(w3, h3);
if (w1!=w2) {
ip3.setColor(background);
ip3.fill();
}
if (i<=d1) {
ip3.insert(stack1.getProcessor(1),0,0);
if (stack2!=stack1)
stack1.deleteSlice(1);
}
if (i<=d2) {
ip3.insert(stack2.getProcessor(1),0,h1);
stack2.deleteSlice(1);
}
stack3.addSlice(null, ip3);
}
return stack3;
}
boolean showDialog() {
int[] wList = WindowManager.getIDList();
if (wList==null || wList.length<2) {
error();
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("Combiner");
gd.addChoice("Stack1:", titles, titles[0]);
gd.addChoice("Stack2:", titles, titles[1]);
gd.addCheckbox("Combine vertically", false);
gd.addHelp(IJ.URL+"/docs/menus/image.html#combine");
gd.showDialog();
if (gd.wasCanceled())
return false;
int[] index = new int[3];
int index1 = gd.getNextChoiceIndex();
int index2 = gd.getNextChoiceIndex();
imp1 = WindowManager.getImage(wList[index1]);
imp2 = WindowManager.getImage(wList[index2]);
vertical = gd.getNextBoolean();
return true;
}
void error() {
IJ.error("StackCombiner", "This command requires two stacks\n"
+"that are the same data type.");
}
}
|