Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.awt.Color;
- import java.awt.Graphics2D;
- import java.awt.Rectangle;
- import java.awt.geom.AffineTransform;
- import java.awt.geom.Area;
- import java.awt.image.BufferedImage;
- import java.awt.image.DataBufferByte;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.TreeMap;
- import java.util.TreeSet;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Future;
- import amira.AmiraMeshEncoder;
- import ij.IJ;
- import ij.ImageJ;
- import ij.ImagePlus;
- import ij.ImageStack;
- import ij.gui.Roi;
- import ij.io.FileSaver;
- import ij.measure.Calibration;
- import ij.process.ByteProcessor;
- import ij.process.FloatProcessor;
- import ij.process.ImageProcessor;
- import ij.process.ShortProcessor;
- import ini.trakem2.Project;
- import ini.trakem2.display.*;
- import ini.trakem2.display.paint.USHORTPaint;
- import ini.trakem2.tree.ProjectThing;
- import ini.trakem2.utils.Utils;
- destdir="/home/john/tmp/tem2/";
- public static void writeArealists( String destdir, ProjectThing root, String prefix,
- LayerSet layer_set,
- Roi roi, float scale )
- {
- // put a check here to be sure root is okay
- if( root == null )
- return;
- // add this object's title to the file name
- String thisprefix = prefix + "_" + root.getTitle();
- // get this project's object and see if it's an AreaList
- Object obj = root.getObject();
- if( obj instanceof AreaList )
- {
- // if so, write a tif
- ImagePlus imp = exportAsMask( (AreaList)obj, layer_set, roi, scale );
- System.out.println( "the imp mask : " + imp );
- System.out.println( "writing: " + thisprefix );
- IJ.save( imp, destdir + thisprefix + ".tif" );
- }
- // recurse
- children = root.getChildren();
- if( children != null )
- {
- for( int i = 0; i < children.size(); i++ )
- {
- ProjectThing c = children.get( i );
- writeArealists( destdir, c, thisprefix, layer_set, roi, scale );
- }
- }
- }
- static public ImagePlus exportAsMask( AreaList al, LayerSet layer_set, ij.gui.Roi roi, float scale )
- {
- //layer_ids = al.getLayerIds();
- //int first_layer = al.
- //int last_layer
- list = new ArrayList();
- list.add( al );
- // Compute highest label value, which affects of course the stack image type
- label_values = new TreeSet();
- for (Displayable d : list) {
- String label = d.getProperty("label");
- if (null != label) label_values.add(Integer.parseInt(label));
- }
- int lowest=0, highest=0;
- if (label_values.size() > 0) {
- lowest = label_values.first();
- highest = label_values.last();
- }
- int n_non_labeled = list.size() - label_values.size();
- int max_label_value = highest + n_non_labeled;
- int type_ = ImagePlus.GRAY8;
- if (max_label_value > 255) {
- type_ = ImagePlus.GRAY16;
- if (max_label_value > 65535) {
- type_ = ImagePlus.GRAY32;
- }
- }
- int type = type_;
- int width,height;
- Rectangle broi;
- if (null == roi) {
- broi = null;
- width = (int)(layer_set.getLayerWidth() * scale);
- height = (int)(layer_set.getLayerHeight() * scale);
- } else {
- broi = roi.getBounds();
- width = (int)(broi.width * scale);
- height = (int)(broi.height * scale);
- }
- ImageStack stack = new ImageStack(width, height);
- Calibration cal = layer_set.getCalibration();
- //float len = last_layer - first_layer + 1;
- //layers = layer_set.getLayers().subList(first_layer, last_layer+1);
- layers = al.getLayerRange();
- float len = (float)layers.size();
- slices = Collections.synchronizedMap(new TreeMap());
- for (int k = 0; k < layers.size(); k++) {
- Layer la = layers.get(k);
- int slice = k;
- Utils.showProgress(slice / len);
- ImageProcessor ip;
- if (ImagePlus.GRAY8 == type) {
- BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
- Graphics2D g = bi.createGraphics();
- for (AreaList ali : list) {
- Area area = ali.getArea(la);
- if (null == area || area.isEmpty()) continue;
- // Transform: the scale and the roi
- AffineTransform aff = new AffineTransform();
- // reverse order of transformations:
- /* 3 - To scale: */ if (1 != scale) aff.scale(scale, scale);
- /* 2 - To roi coordinates: */ if (null != broi) aff.translate(-broi.x, -broi.y);
- /* 1 - To world coordinates: */ aff.concatenate(ali.getAffineTransform());
- g.setTransform(aff);
- int label = 255;
- g.setColor(new Color(label, label, label));
- g.fill(area);
- }
- g.dispose();
- ip = new ByteProcessor(bi);
- bi.flush();
- } else if (ImagePlus.GRAY16 == type) {
- USHORTPaint paint = new USHORTPaint((short)0);
- BufferedImage bi = new BufferedImage(paint.getComponentColorModel(), paint.getComponentColorModel().createCompatibleWritableRaster(width, height), false, null);
- Graphics2D g = bi.createGraphics();
- //ColorSpace ugray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
- int painted = 0;
- for (AreaList ali : list) {
- Area area = ali.getArea(la);
- if (null == area || area.isEmpty()) continue;
- // Transform: the scale and the roi
- AffineTransform aff = new AffineTransform();
- // reverse order of transformations:
- /* 3 - To scale: */ if (1 != scale) aff.scale(scale, scale);
- /* 2 - To roi coordinates: */ if (null != broi) aff.translate(-broi.x, -broi.y);
- /* 1 - To world coordinates: */ aff.concatenate(ali.at);
- // Fill
- g.setTransform(aff);
- // The color doesn't work: paints in a stretched 8-bit mode
- //g.setColor(new Color(ugray, new float[]{((float)labels.get(d)) / range}, 1));
- short ls = (short)255;
- paint.setValue(ls);
- g.setPaint(paint);
- g.fill(area); //.createTransformedArea(aff));
- painted += 1;
- }
- g.dispose();
- ip = new ShortProcessor(bi);
- bi.flush();
- Utils.log2("painted: " + painted);
- } else {
- // Option 1: could use the same as above, but shifted by 65536, so that 65537 is 1, 65538 is 2, etc.
- // and keep doing it until no more need to be shifted.
- // The PROBLEM: cannot keep the order without complicated gymnastics to remember
- // which label in which image has to be merged to the final image, which prevent
- // a simple one-pass blitter.
- //
- // Option 2: paint each arealist, extract the image, use it as a mask for filling:
- FloatProcessor fp = new FloatProcessor(width, height);
- float[] fpix = (float[]) fp.getPixels();
- ip = fp;
- BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
- Graphics2D gbi = bi.createGraphics();
- for (AreaList ali : list) {
- Area area = ali.getArea(la);
- if (null == area || area.isEmpty()) {
- continue;
- }
- // Transform: the scale and the roi
- // reverse order of transformations:
- AffineTransform aff = new AffineTransform();
- /* 3 - To scale: */ if (1 != scale) aff.scale(scale, scale);
- /* 2 - To ROI coordinates: */ if (null != broi) aff.translate(-broi.x, -broi.y);
- /* 1 - To world coordinates: */ aff.concatenate(ali.at);
- Area s = area.createTransformedArea(aff);
- Rectangle sBounds = s.getBounds();
- // Need to paint at all?
- if (0 == sBounds.width || 0 == sBounds.height || !sBounds.intersects(0, 0, width, height)) continue;
- // Paint shape
- gbi.setColor(Color.white);
- gbi.fill(s);
- // Read out painted region
- int x0 = Math.max(0, sBounds.x);
- int y0 = Math.max(0, sBounds.y);
- int xN = Math.min(width, sBounds.x + sBounds.width);
- int yN = Math.min(height, sBounds.y + sBounds.height);
- // Get the array
- byte[] bpix = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
- float value = 255f;
- // For every non-black pixel, set a 'value' pixel in the FloatProcessor
- for (int y = y0; y < yN; ++y) {
- for (int x = x0; x < xN; ++x) {
- int pos = y * width + x;
- if (0 == bpix[pos]) continue; // black
- fpix[pos] = value;
- }
- }
- // Clear image region
- gbi.setColor(Color.black);
- gbi.fill(s);
- }
- gbi.dispose();
- bi.flush();
- }
- slices.put(slice, ip);
- }
- for ( e : slices.entrySet()) {
- Layer la = layers.get(e.getKey());
- stack.addSlice(la.getZ() * cal.pixelWidth + "", e.getValue());
- if (ImagePlus.GRAY8 != type) {
- e.getValue().setMinAndMax(lowest, highest);
- }
- }
- Utils.showProgress(1);
- // Save via file dialog:
- ImagePlus imp = new ImagePlus("Labels", stack);
- imp.setCalibration(layer_set.getCalibrationCopy());
- return imp;
- }
- // get the root ProjectThing
- project = Project.getProjects().get(0);
- root = project.getRootProjectThing();
- layer_set = project.getRootLayerSet();
- //first = 0;
- //last = layer_set.size() - 1;
- scale = 1.0f;
- prefix = "";
- // call the function
- writeArealists( destdir, root, prefix,
- layer_set, null, scale );
Add Comment
Please, Sign In to add comment