package ij.plugin;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.awt.image.ColorModel;
import java.util.Properties;
import ij.*;
import ij.io.*;
import ij.gui.*;
import ij.process.*;
import ij.measure.Calibration;
import ij.util.*;

/** Implements the File/Import/Image Sequence command, which
	opens a folder of images as a stack. */
public class FolderOpener implements PlugIn {

	private static String[] excludedTypes = {".txt", ".lut", ".roi", ".pty", ".hdr", ".java", ".ijm", ".py", ".js", ".bsh", ".xml"};
	private static boolean staticSortFileNames = true;
	private static boolean staticOpenAsVirtualStack;
	private boolean convertToRGB;
	private boolean sortFileNames = true;
	private boolean openAsVirtualStack;
	private double scale = 100.0;
	private int n, start, increment;
	private String filter;
	private String legacyRegex;
	private FileInfo fi;
	private String info1;
	private ImagePlus image;
	private boolean saveImage;
	private long t0;
	
	/** Opens the images in the specified directory as a stack. Displays
		directory chooser and options dialogs if the argument is null. */
	public static ImagePlus open(String path) {
		return open(path, null);
	}

	/** Opens the images in the specified directory as a stack. Opens
		the images as a virtual stack if the 'options' string contains
		"virtual". Displays directory chooser and options dialogs if the
		the 'path' argument is null. */
	public static ImagePlus open(String path, String options) {
		FolderOpener fo = new FolderOpener();
		fo.saveImage = true;
		fo.openAsVirtualStack = options!=null && options.contains("virtual");
		fo.run(path);
		return fo.image;
	}

	/** Opens the images in the specified directory as a stack. Displays
		directory chooser and options dialogs if the argument is null. */
	public ImagePlus openFolder(String path) {
		saveImage = true;
		run(path);
		return image;
	}

	public void run(String arg) {
		boolean isMacro = Macro.getOptions()!=null;
		String directory = null;
		if (arg!=null && !arg.equals("")) {
			directory = arg;
		} else {
			if (!isMacro) {
				sortFileNames = staticSortFileNames;
				openAsVirtualStack = staticOpenAsVirtualStack;
			}
			arg = null;
			String title = "Open Image Sequence...";
			String macroOptions = Macro.getOptions();
			if (macroOptions!=null) {
				directory = Macro.getValue(macroOptions, title, null);
				if (directory!=null) {
					directory = OpenDialog.lookupPathVariable(directory);
					File f = new File(directory);
					if (!f.isDirectory() && (f.exists()||directory.lastIndexOf(".")>directory.length()-5))
						directory = f.getParent();
				}
				legacyRegex = Macro.getValue(macroOptions, "or", "");
				if (legacyRegex.equals(""))
					legacyRegex = null;
			}
			if (directory==null) {
				if (Prefs.useFileChooser && !IJ.isMacOSX()) {
					OpenDialog od = new OpenDialog(title, arg);
					directory = od.getDirectory();
					String name = od.getFileName();
					if (name==null)
						return;
				} else
					directory = IJ.getDirectory(title);
			}
		}
		if (directory==null)
			return;
		String[] list = (new File(directory)).list();
		if (list==null)
			return;
		String title = directory;
		if (title.endsWith(File.separator) || title.endsWith("/"))
			title = title.substring(0, title.length()-1);
		int index = title.lastIndexOf(File.separatorChar);
		if (index!=-1) title = title.substring(index + 1);
		if (title.endsWith(":"))
			title = title.substring(0, title.length()-1);
		
		IJ.register(FolderOpener.class);
		list = trimFileList(list);
		if (list==null) return;
		if (IJ.debugMode) IJ.log("FolderOpener: "+directory+" ("+list.length+" files)");
		int width=0, height=0, stackSize=1, bitDepth=0;
		ImageStack stack = null;
		double min = Double.MAX_VALUE;
		double max = -Double.MAX_VALUE;
		Calibration cal = null;
		boolean allSameCalibration = true;
		IJ.resetEscape();		
		Overlay overlay = null;
		n = list.length;
		start = 1;
		increment = 1;
		try {
			if (isMacro) {
				if (!showDialog(null, list))
					return;
			} else {
				for (int i=0; ilist.length)
				start = 1;
			if (start+n-1>list.length)
				n = list.length-start+1;
			int count = 0;
			int counter = 0;
			ImagePlus imp = null;
			boolean firstMessage = true;
			boolean fileInfoStack = false;
			for (int i=start-1; i1) {
							stack = new FileInfoVirtualStack();
							fileInfoStack = true;
						} else
							stack = new VirtualStack(width, height, cm, directory);
						((VirtualStack)stack).setBitDepth(bitDepth);
					} else if (scale<100.0)						
						stack = new ImageStack((int)(width*scale/100.0), (int)(height*scale/100.0), cm);
					else
						stack = new ImageStack(width, height, cm);
					info1 = (String)imp.getProperty("Info");
				}
				if (imp==null)
					continue;
				if (imp.getWidth()!=width || imp.getHeight()!=height) {
					IJ.log(list[i] + ": wrong size; "+width+"x"+height+" expected, "+imp.getWidth()+"x"+imp.getHeight()+" found");
					continue;
				}
				String label = imp.getTitle();
				if (stackSize==1) {
					String info = (String)imp.getProperty("Info");
					if (info!=null)
						label += "\n" + info;
				}
				if (Math.abs(imp.getCalibration().pixelWidth-cal.pixelWidth)>0.0000000001)
					allSameCalibration = false;
				ImageStack inputStack = imp.getStack();
				Overlay overlay2 = imp.getOverlay();
				if (overlay2!=null && !openAsVirtualStack) {
					if (overlay==null)
						overlay = new Overlay();
					for (int j=0; j1) {
							String sliceLabel = inputStack.getSliceLabel(slice);
							if (sliceLabel!=null)
								label2=sliceLabel;
							else if (label2!=null && !label2.equals(""))
								label2 += ":"+slice;
						}
						ip = inputStack.getProcessor(slice);
						if (convertToRGB) {
							ip = ip.convertToRGB();
							bitDepth2 = 24;
						}
						if (bitDepth2!=bitDepth) {
							if (bitDepth==8 && bitDepth2==24) {
								ip = ip.convertToByte(true);
								bitDepth2 = 8;
							} else if (bitDepth==32) {
								ip = ip.convertToFloat();
								bitDepth2 = 32;
							} else if (bitDepth==24) {
								ip = ip.convertToRGB();
								bitDepth2 = 24;
							}
						}
						if (bitDepth2!=bitDepth) {
							IJ.log(list[i] + ": wrong bit depth; "+bitDepth+" expected, "+bitDepth2+" found");
							break;
						}
						if (scale<100.0)
							ip = ip.resize((int)(width*scale/100.0), (int)(height*scale/100.0));
						if (ip.getMin()max) max = ip.getMax();
						stack.addSlice(label2, ip);
					}
				}
				count++;
				IJ.showStatus(count+"/"+n);
				IJ.showProgress(count, n);
				if (count>=n) 
					break;
				if (IJ.escapePressed())
					{IJ.beep(); break;}
			}
		} catch(OutOfMemoryError e) {
			IJ.outOfMemory("FolderOpener");
			if (stack!=null) stack.trim();
		}
		if (stack!=null && stack.getSize()>0) {
			ImagePlus imp2 = new ImagePlus(title, stack);
			if (imp2.getType()==ImagePlus.GRAY16 || imp2.getType()==ImagePlus.GRAY32)
				imp2.getProcessor().setMinAndMax(min, max);
			if (fi==null)
				fi = new FileInfo();
			fi.fileFormat = FileInfo.UNKNOWN;
			fi.fileName = "";
			fi.directory = directory;
			imp2.setFileInfo(fi); // saves FileInfo of the first image
			imp2.setOverlay(overlay);
			if (stack instanceof VirtualStack) {
				Properties props = ((VirtualStack)stack).getProperties();
				if (props!=null)
					imp2.setProperty("FHT", props.get("FHT"));
			}
			if (allSameCalibration) {
				// use calibration from first image
				if (scale!=100.0 && cal.scaled()) {
					cal.pixelWidth /= scale/100.0;
					cal.pixelHeight /= scale/100.0;
				}
				if (cal.pixelWidth!=1.0 && cal.pixelDepth==1.0)
					cal.pixelDepth = cal.pixelWidth;
				imp2.setCalibration(cal);
			}
			if (info1!=null && info1.lastIndexOf("7FE0,0010")>0) {
				stack = DicomTools.sort(stack);
				imp2.setStack(stack);
				double voxelDepth = DicomTools.getVoxelDepth(stack);
				if (voxelDepth>0.0) {
					if (IJ.debugMode) IJ.log("DICOM voxel depth set to "+voxelDepth+" ("+cal.pixelDepth+")");
					cal.pixelDepth = voxelDepth;
					imp2.setCalibration(cal);
				}
			}
			if (imp2.getStackSize()==1) {
				imp2.setProperty("Label", list[0]);
				if (info1!=null)
					imp2.setProperty("Info", info1);
			}
			if (arg==null && !saveImage) {
				String time = (System.currentTimeMillis()-t0)/1000.0 + " seconds";
				imp2.show(time);
				if (stack.isVirtual()) {
					overlay = stack.getProcessor(1).getOverlay();
					if (overlay!=null)
						imp2.setOverlay(overlay);
				}
			}
			if (saveImage)
				image = imp2;
		}
		IJ.showProgress(1.0);
	}
	
	private void openAsFileInfoStack(FileInfoVirtualStack stack, String path) {
		FileInfo[] info = Opener.getTiffFileInfo(path);
		if (info==null || info.length==0)
			return;
		int n =info[0].nImages;
		if (info.length==1 && n>1) {
			long size = fi.width*fi.height*fi.getBytesPerPixel();
			for (int i=0; i100.0) scale = 100.0;
		filter = gd.getNextString();
		if (legacyRegex!=null)
			filter = "("+legacyRegex+")";
		convertToRGB = gd.getNextBoolean();
		sortFileNames = gd.getNextBoolean();
		openAsVirtualStack = gd.getNextBoolean();
		if (openAsVirtualStack)
			scale = 100.0;
		if (!IJ.macroRunning()) {
			staticSortFileNames = sortFileNames;
			staticOpenAsVirtualStack = openAsVirtualStack;
		}
		return true;
	}
	
	public static String[] getFilteredList(String[] list, String filter, String title) {
		boolean isRegex = false;
		if (filter!=null && (filter.equals("") || filter.equals("*")))
			filter = null;
		if (list==null || filter==null)
			return list;
		if (title==null) {
			String[] list2 = new String[list.length];
			for (int i=0; i=2 && filter.startsWith("(")&&filter.endsWith(")")) {
			filter = filter.substring(1,filter.length()-1);
			isRegex = true;
		}
		int filteredImages = 0;
		for (int i=0; i0)
				msg = msg.substring(0,index);
			IJ.showStatus("Regex error: "+msg);
			contains = true;
		}
		return contains;
	}

	/** Removes names that start with "." or end with ".db", ".txt", ".lut", "roi", ".pty", ".hdr", ".py", etc. */
	public String[] trimFileList(String[] rawlist) {
		int count = 0;
		for (int i=0; i< rawlist.length; i++) {
			String name = rawlist[i];
			if (name.startsWith(".")||name.equals("Thumbs.db")||excludedFileType(name))
				rawlist[i] = null;
			else
				count++;
		}
		if (count==0) return null;
		String[] list = rawlist;
		if (count100.0) scale = 100.0;
			if (n<1) n = fileCount;
			if (start<1 || start>fileCount) start = 1;
			if (start+n-1>fileCount)
				n = fileCount-start+1;
			if (inc<1) inc = 1;
			TextField tf = (TextField)stringField.elementAt(0);
			String filter = tf.getText();
			int n3 = Integer.MAX_VALUE;
			String[] filteredList = getFilteredList(list, filter, null);
			if (filteredList!=null)
				n3 = filteredList.length;
			else
				n3 = 0;
			if (n3n) n2 = n;
			double size = ((double)width*height*n2*bytesPerPixel)/(1024*1024);
			((Label)theLabel).setText(width+" x "+height+" x "+n2+" ("+IJ.d2s(size,1)+"MB)");
		}
	
		public int getNumber(Object field) {
			TextField tf = (TextField)field;
			String theText = tf.getText();
			double value;
			Double d;
			try {d = new Double(theText);}
			catch (NumberFormatException e){
				d = null;
			}
			if (d!=null)
				return (int)d.doubleValue();
			else
				return 0;
		  }
	
	} // FolderOpenerDialog

} // FolderOpener



 

Ads help maintain this website.