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 188 189 190 191 192 193 194 195 196 197 198 199
|
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.io.*;
import ij.util.Tools;
import java.awt.*;
import java.io.*;
import java.util.*;
/** This plugin opens images specified by list of file paths as a virtual stack.
It implements the File/Import/Stack From List command. */
public class ListVirtualStack extends VirtualStack implements PlugIn {
private static boolean virtual;
private String[] list;
private String[] labels;
private int nImages;
private int imageWidth, imageHeight;
public void run(String arg) {
OpenDialog od = new OpenDialog("Open Image List", arg);
String name = od.getFileName();
if (name==null) return;
String dir = od.getDirectory();
//IJ.log("ListVirtualStack: "+dir+" "+name);
list = open(dir+name);
if (list==null) return;
nImages = list.length;
labels = new String[nImages];
//for (int i=0; i<list.length; i++)
// IJ.log(i+" "+list[i]);
if (list.length==0) {
IJ.error("Stack From List", "The file path list is empty");
return;
}
if (!list[0].startsWith("http://")) {
File f = new File(list[0]);
if (!f.exists()) {
IJ.error("Stack From List", "The first file on the list does not exist:\n \n"+list[0]);
return;
}
}
ImagePlus imp = IJ.openImage(list[0]);
if (imp==null) return;
imageWidth = imp.getWidth();
imageHeight = imp.getHeight();
setBitDepth(imp.getBitDepth());
ImageStack stack = this;
if (!showDialog(imp)) return;
if (!virtual)
stack = convertToRealStack(imp);
ImagePlus imp2 = new ImagePlus(name, stack);
imp2.setCalibration(imp.getCalibration());
imp2.show();
}
boolean showDialog(ImagePlus imp) {
double bytesPerPixel = 1;
switch (imp.getType()) {
case ImagePlus.GRAY16:
bytesPerPixel=2; break;
case ImagePlus.COLOR_RGB:
case ImagePlus.GRAY32:
bytesPerPixel=4; break;
}
double size = (imageWidth*imageHeight*bytesPerPixel)/(1024.0*1024.0);
int digits = size*getSize()<10.0?1:0;
String size1 = IJ.d2s(size*getSize(), digits)+" MB";
String size2 = IJ.d2s(size,1)+" MB";
GenericDialog gd = new GenericDialog("Open Stack From List");
gd.addCheckbox("Use Virtual Stack", virtual);
gd.addMessage("This "+imageWidth+"x"+imageHeight+"x"+getSize()+" stack will require "+size1+",\n or "+size2+" if opened as a virtual stack.");
gd.showDialog();
if (gd.wasCanceled()) return false;
virtual = gd.getNextBoolean();
return true;
}
ImageStack convertToRealStack(ImagePlus imp) {
ImageStack stack2 = new ImageStack(imageWidth, imageHeight, imp.getProcessor().getColorModel());
int n = this.getSize();
for (int i=1; i<=this.getSize(); i++) {
IJ.showProgress(i, n);
IJ.showStatus("Opening: "+i+"/"+n);
ImageProcessor ip2 = this.getProcessor(i);
if (ip2!=null)
stack2.addSlice(this.getSliceLabel(i), ip2);
}
return stack2;
}
String[] open(String path) {
if (path.startsWith("http://"))
return openUrl(path);
Vector v = new Vector();
File file = new File(path);
try {
BufferedReader r = new BufferedReader(new FileReader(file));
while (true) {
String s=r.readLine();
if (s==null || s.equals("") || s.startsWith(" "))
break;
else
v.addElement(s);
}
r.close();
String[] list = new String[v.size()];
v.copyInto((String[])list);
return list;
}
catch (Exception e) {
IJ.error("Open List Error \n\""+e.getMessage()+"\"\n");
}
return null;
}
String[] openUrl(String url) {
String str = IJ.openUrlAsString(url);
if (str.startsWith("<Error: ")) {
IJ.error("Stack From List", str);
return null;
} else
return Tools.split(str, "\n");
}
/** Deletes the specified image, were 1<=n<=nslices. */
public void deleteSlice(int n) {
if (n<1 || n>nImages)
throw new IllegalArgumentException("Argument out of range: "+n);
if (nImages<1) return;
for (int i=n; i<nImages; i++)
list[i-1] = list[i];
list[nImages-1] = null;
nImages--;
}
/** Returns an ImageProcessor for the specified slice,
were 1<=n<=nslices. Returns null if the stack is empty.
*/
public ImageProcessor getProcessor(int n) {
if (n<1 || n>nImages)
throw new IllegalArgumentException("Argument out of range: "+n);
IJ.redirectErrorMessages();
String url = list[n-1];
ImagePlus imp = null;
if (url.length()>0)
imp = IJ.openImage(url);
if (imp!=null) {
labels[n-1] = (new File(list[n-1])).getName()+"\n"+(String)imp.getProperty("Info");
ImageProcessor ip = imp.getProcessor();
int bitDepth = getBitDepth();
if (imp.getBitDepth()!=bitDepth) {
switch (bitDepth) {
case 8: ip=ip.convertToByte(true); break;
case 16: ip=ip.convertToShort(true); break;
case 24: ip=ip.convertToRGB(); break;
case 32: ip=ip.convertToFloat(); break;
}
}
if (ip.getWidth()!=imageWidth || ip.getHeight()!=imageHeight)
ip = ip.resize(imageWidth, imageHeight);
return ip;
} else {
ImageProcessor ip = null;
switch (getBitDepth()) {
case 8: ip=new ByteProcessor(imageWidth,imageHeight); break;
case 16: ip=new ShortProcessor(imageWidth,imageHeight); break;
case 24: ip=new ColorProcessor(imageWidth,imageHeight); break;
case 32: ip=new FloatProcessor(imageWidth,imageHeight); break;
}
return ip;
}
}
/** Returns the number of images in this stack. */
public int getSize() {
return nImages;
}
/** Returns the name of the specified image. */
public String getSliceLabel(int n) {
if (n<1 || n>nImages)
throw new IllegalArgumentException("Argument out of range: "+n);
if (labels[n-1]!=null)
return labels[n-1];
else
return (new File(list[n-1])).getName();
}
public int getWidth() {
return imageWidth;
}
public int getHeight() {
return imageHeight;
}
}
|