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 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
package ij;
import ij.process.*;
import ij.io.*;
import ij.gui.ImageCanvas;
import ij.util.Tools;
import java.io.*;
import java.awt.Font;
import java.awt.image.ColorModel;
/** This class represents an array of disk-resident images. */
public class VirtualStack extends ImageStack {
private static final int INITIAL_SIZE = 100;
private String path;
private int nSlices;
private String[] names;
private String[] labels;
private int bitDepth;
/** Default constructor. */
public VirtualStack() { }
/** Creates a new, empty virtual stack. */
public VirtualStack(int width, int height, ColorModel cm, String path) {
super(width, height, cm);
this.path = path;
names = new String[INITIAL_SIZE];
labels = new String[INITIAL_SIZE];
//IJ.log("VirtualStack: "+path);
}
/** Adds an image to the end of the stack. */
public void addSlice(String name) {
if (name==null)
throw new IllegalArgumentException("'name' is null!");
nSlices++;
//IJ.log("addSlice: "+nSlices+" "+name);
if (nSlices==names.length) {
String[] tmp = new String[nSlices*2];
System.arraycopy(names, 0, tmp, 0, nSlices);
names = tmp;
tmp = new String[nSlices*2];
System.arraycopy(labels, 0, tmp, 0, nSlices);
labels = tmp;
}
names[nSlices-1] = name;
}
/** Does nothing. */
public void addSlice(String sliceLabel, Object pixels) {
}
/** Does nothing.. */
public void addSlice(String sliceLabel, ImageProcessor ip) {
}
/** Does noting. */
public void addSlice(String sliceLabel, ImageProcessor ip, int n) {
}
/** Deletes the specified slice, were 1<=n<=nslices. */
public void deleteSlice(int n) {
if (n<1 || n>nSlices)
throw new IllegalArgumentException("Argument out of range: "+n);
if (nSlices<1)
return;
for (int i=n; i<nSlices; i++)
names[i-1] = names[i];
names[nSlices-1] = null;
nSlices--;
}
/** Deletes the last slice in the stack. */
public void deleteLastSlice() {
if (nSlices>0)
deleteSlice(nSlices);
}
/** Returns the pixel array for the specified slice, were 1<=n<=nslices. */
public Object getPixels(int n) {
ImageProcessor ip = getProcessor(n);
if (ip!=null)
return ip.getPixels();
else
return null;
}
/** Assigns a pixel array to the specified slice,
were 1<=n<=nslices. */
public void setPixels(Object pixels, int n) {
}
/** Returns an ImageProcessor for the specified slice,
were 1<=n<=nslices. Returns null if the stack is empty.
*/
public ImageProcessor getProcessor(int n) {
//IJ.log("getProcessor: "+n+" "+names[n-1]+" "+bitDepth);
Opener opener = new Opener();
opener.setSilentMode(true);
IJ.redirectErrorMessages(true);
ImagePlus imp = opener.openImage(path, names[n-1]);
IJ.redirectErrorMessages(false);
ImageProcessor ip = null;
int depthThisImage = 0;
if (imp!=null) {
int w = imp.getWidth();
int h = imp.getHeight();
int type = imp.getType();
ColorModel cm = imp.getProcessor().getColorModel();
labels[n-1] = (String)imp.getProperty("Info");
depthThisImage = imp.getBitDepth();
ip = imp.getProcessor();
} else {
File f = new File(path, names[n-1]);
String msg = f.exists()?"Error opening ":"File not found: ";
ip = new ByteProcessor(getWidth(), getHeight());
ip.invert();
int size = getHeight()/20;
if (size<9) size=9;
Font font = new Font("Helvetica", Font.PLAIN, size);
ip.setFont(font);
ip.setAntialiasedText(true);
ip.setColor(0);
ip.drawString(msg+names[n-1], size, size*2);
depthThisImage = 8;
}
if (depthThisImage!=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()!=getWidth() || ip.getHeight()!=getHeight()) {
ImageProcessor ip2 = ip.createProcessor(getWidth(), getHeight());
ip2.insert(ip, 0, 0);
ip = ip2;
}
return ip;
}
/** Currently not implemented */
public int saveChanges(int n) {
return -1;
}
/** Returns the number of slices in this stack. */
public int getSize() {
return nSlices;
}
/** Returns the label of the Nth image. */
public String getSliceLabel(int n) {
String label = labels[n-1];
if (label==null)
return names[n-1];
else if (label.length()<=60)
return label;
else
return names[n-1]+"\n"+label;
}
/** Returns null. */
public Object[] getImageArray() {
return null;
}
/** Does nothing. */
public void setSliceLabel(String label, int n) {
}
/** Always return true. */
public boolean isVirtual() {
return true;
}
/** Does nothing. */
public void trim() {
}
/** Returns the path to the directory containing the images. */
public String getDirectory() {
return path;
}
/** Returns the file name of the specified slice, were 1<=n<=nslices. */
public String getFileName(int n) {
return names[n-1];
}
/** Sets the bit depth (8, 16, 24 or 32). */
public void setBitDepth(int bitDepth) {
this.bitDepth = bitDepth;
}
/** Returns the bit depth (8, 16, 24 or 32), or 0 if the bit depth is not known. */
public int getBitDepth() {
return bitDepth;
}
public ImageStack sortDicom(String[] strings, String[] info, int maxDigits) {
int n = getSize();
String[] names2 = new String[n];
for (int i=0; i<n; i++)
names2[i] = names[i];
for (int i=0; i<n; i++) {
int slice = (int)Tools.parseDouble(strings[i].substring(strings[i].length()-maxDigits), 0.0);
if (slice==0) return null;
names[i] = names2[slice-1];
labels[i] = info[slice-1];
}
return this;
}
}
|