use of ij.process.ByteProcessor in project mcib3d-core by mcib3d.
the class Object3DVoxels method createRoi.
/**
* @param z Description of the Parameter
* @return Description of the Return Value
* @deprecated use Object3D-IJUtils
* Constructor for the createRoi object
*/
@Override
public Roi createRoi(int z) {
// IJ.write("create roi " + z);
int sx = this.getXmax() - this.getXmin() + 1;
int sy = this.getYmax() - this.getYmin() + 1;
ByteProcessor mask = new ByteProcessor(sx, sy);
// object black on white
// mask.invert();
draw(mask, z, 255);
ImagePlus maskPlus = new ImagePlus("mask " + z, mask);
// maskPlus.show();
// IJ.run("Create Selection");
ThresholdToSelection tts = new ThresholdToSelection();
tts.setup("", maskPlus);
tts.run(mask);
maskPlus.updateAndDraw();
// IJ.write("sel=" + maskPlus.getRoi());
// maskPlus.hide();
Roi roi = maskPlus.getRoi();
Rectangle rect = roi.getBounds();
rect.x += this.getXmin();
rect.y += this.getYmin();
return roi;
}
use of ij.process.ByteProcessor in project imagej-ops by imagej.
the class AddOpBenchmarkTest method initImg.
/**
* Sets up test images
*/
@Before
public void initImg() {
final int w = 15000, h = 15000;
in = generateByteArrayTestImg(true, w, h);
out = generateByteArrayTestImg(false, w, h);
arrIn = in.update(null).getCurrentStorageArray();
arrOut = in.update(null).getCurrentStorageArray();
imp = new ImagePlus("imp", new ByteProcessor(w, h, arrIn));
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class AreaList method exportAsLabels.
/**
* Export all given AreaLists as one per pixel value, what is called a "labels" file; a file dialog is offered to save the image as a tiff stack.
*/
public static void exportAsLabels(final List<Displayable> listToPaint, final ij.gui.Roi roi, final float scale, int first_layer, int last_layer, final boolean visible_only, final boolean to_file, final boolean as_amira_labels) {
// survive everything:
if (null == listToPaint || 0 == listToPaint.size()) {
Utils.log("Null or empty list.");
return;
}
if (scale < 0 || scale > 1) {
Utils.log("Improper scale value. Must be 0 < scale <= 1");
return;
}
// Select the subset to paint
final ArrayList<AreaList> list = new ArrayList<AreaList>();
for (final Displayable d : listToPaint) {
if (visible_only && !d.isVisible())
continue;
if (d instanceof AreaList)
list.add((AreaList) d);
}
Utils.log2("exportAsLabels: list.size() is " + list.size());
// Current AmiraMeshEncoder supports ByteProcessor only: 256 labels max, including background at zero.
if (as_amira_labels && list.size() > 255) {
Utils.log("Saving ONLY first 255 AreaLists!\nDiscarded:");
final StringBuilder sb = new StringBuilder();
for (final Displayable d : list.subList(255, list.size())) {
sb.append(" ").append(d.getProject().getShortMeaningfulTitle(d)).append('\n');
}
Utils.log(sb.toString());
final ArrayList<AreaList> li = new ArrayList<AreaList>(list);
list.clear();
list.addAll(li.subList(0, 255));
}
String path = null;
if (to_file) {
final String ext = as_amira_labels ? ".am" : ".tif";
final File f = Utils.chooseFile("labels", ext);
if (null == f)
return;
path = f.getAbsolutePath().replace('\\', '/');
}
final LayerSet layer_set = list.get(0).getLayerSet();
if (first_layer > last_layer) {
final int tmp = first_layer;
first_layer = last_layer;
last_layer = tmp;
if (first_layer < 0)
first_layer = 0;
if (last_layer >= layer_set.size())
last_layer = layer_set.size() - 1;
}
// Create image according to roi and scale
final int width, height;
final 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);
}
// Compute highest label value, which affects of course the stack image type
final TreeSet<Integer> label_values = new TreeSet<Integer>();
for (final Displayable d : list) {
final 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();
}
final int n_non_labeled = list.size() - label_values.size();
final 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;
}
}
final int type = type_;
final ImageStack stack = new ImageStack(width, height);
final Calibration cal = layer_set.getCalibration();
String amira_params = null;
if (as_amira_labels) {
final StringBuilder sb = new StringBuilder("CoordType \"uniform\"\nMaterials {\nExterior {\n Id 0,\nColor 0 0 0\n}\n");
final float[] c = new float[3];
int value = 0;
for (final Displayable d : list) {
// 0 is background
value++;
d.getColor().getRGBColorComponents(c);
String s = d.getProject().getShortMeaningfulTitle(d);
s = s.replace('-', '_').replaceAll(" #", " id");
sb.append(Utils.makeValidIdentifier(s)).append(" {\n").append("Id ").append(value).append(",\n").append("Color ").append(c[0]).append(' ').append(c[1]).append(' ').append(c[2]).append("\n}\n");
}
sb.append("}\n");
amira_params = sb.toString();
}
final float len = last_layer - first_layer + 1;
// Assign labels
final HashMap<AreaList, Integer> labels = new HashMap<AreaList, Integer>();
for (final AreaList d : list) {
final String slabel = d.getProperty("label");
int label;
if (null != slabel) {
label = Integer.parseInt(slabel);
} else {
// 0 is background
label = (++highest);
}
labels.put(d, label);
}
final ExecutorService exec = Utils.newFixedThreadPool("labels");
final Map<Integer, ImageProcessor> slices = Collections.synchronizedMap(new TreeMap<Integer, ImageProcessor>());
final List<Future<?>> fus = new ArrayList<Future<?>>();
final List<Layer> layers = layer_set.getLayers().subList(first_layer, last_layer + 1);
for (int k = 0; k < layers.size(); k++) {
final Layer la = layers.get(k);
final int slice = k;
fus.add(exec.submit(new Runnable() {
@Override
public void run() {
Utils.showProgress(slice / len);
final ImageProcessor ip;
if (ImagePlus.GRAY8 == type) {
final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
final Graphics2D g = bi.createGraphics();
for (final AreaList ali : list) {
final Area area = ali.getArea(la);
if (null == area || area.isEmpty())
continue;
// Transform: the scale and the roi
final 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);
g.setTransform(aff);
final int label = labels.get(ali);
g.setColor(new Color(label, label, label));
g.fill(area);
}
g.dispose();
ip = new ByteProcessor(bi);
bi.flush();
} else if (ImagePlus.GRAY16 == type) {
final USHORTPaint paint = new USHORTPaint((short) 0);
final BufferedImage bi = new BufferedImage(paint.getComponentColorModel(), paint.getComponentColorModel().createCompatibleWritableRaster(width, height), false, null);
final Graphics2D g = bi.createGraphics();
// final ColorSpace ugray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
int painted = 0;
for (final AreaList ali : list) {
final Area area = ali.getArea(la);
if (null == area || area.isEmpty())
continue;
// Transform: the scale and the roi
final 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);
// 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));
Utils.log2("value: " + labels.get(ali).shortValue());
paint.setValue(labels.get(ali).shortValue());
g.setPaint(paint);
// .createTransformedArea(aff));
g.fill(area);
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:
final FloatProcessor fp = new FloatProcessor(width, height);
final float[] fpix = (float[]) fp.getPixels();
ip = fp;
final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
final Graphics2D gbi = bi.createGraphics();
for (final AreaList ali : list) {
final Area area = ali.getArea(la);
if (null == area || area.isEmpty()) {
continue;
}
// Transform: the scale and the roi
// reverse order of transformations:
final 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);
final Area s = area.createTransformedArea(aff);
final 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
final int x0 = Math.max(0, sBounds.x);
final int y0 = Math.max(0, sBounds.y);
final int xN = Math.min(width, sBounds.x + sBounds.width);
final int yN = Math.min(height, sBounds.y + sBounds.height);
// Get the array
final byte[] bpix = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
final float value = labels.get(ali);
// 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) {
final int pos = y * width + x;
// black
if (0 == bpix[pos])
continue;
fpix[pos] = value;
}
}
// Clear image region
gbi.setColor(Color.black);
gbi.fill(s);
}
gbi.dispose();
bi.flush();
}
slices.put(slice, ip);
}
}));
}
Utils.wait(fus);
exec.shutdownNow();
for (final Map.Entry<Integer, ImageProcessor> e : slices.entrySet()) {
final 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:
final ImagePlus imp = new ImagePlus("Labels", stack);
if (as_amira_labels)
imp.setProperty("Info", amira_params);
imp.setCalibration(layer_set.getCalibrationCopy());
if (to_file) {
if (as_amira_labels) {
final AmiraMeshEncoder ame = new AmiraMeshEncoder(path);
if (!ame.open()) {
Utils.log("Could not write to file " + path);
return;
}
if (!ame.write(imp)) {
Utils.log("Error in writing Amira file!");
return;
}
} else {
new FileSaver(imp).saveAsTiff(path);
}
} else
imp.show();
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class DisplayCanvas method paintOffscreen.
public BufferedImage paintOffscreen(final Layer active_layer, final List<Layer> layers, final ArrayList<Displayable> al_paint, final Displayable active, final int g_width, final int g_height, final int c_alphas, final Loader loader, final HashMap<Color, Layer> hm, final ArrayList<LayerPanel> blending_list, final int mode, final GraphicsSource graphics_source, final boolean prepaint, int first_non_patch) {
try {
if (0 == g_width || 0 == g_height)
return null;
// ALMOST, but not always perfect //if (null != clipRect) g.setClip(clipRect);
// prepare the canvas for the srcRect and magnification
final AffineTransform atc = new AffineTransform();
atc.scale(magnification, magnification);
atc.translate(-srcRect.x, -srcRect.y);
// the non-srcRect areas, in offscreen coords
final Rectangle r1 = new Rectangle(srcRect.x + srcRect.width, srcRect.y, (int) (g_width / magnification) - srcRect.width, (int) (g_height / magnification));
final Rectangle r2 = new Rectangle(srcRect.x, srcRect.y + srcRect.height, srcRect.width, (int) (g_height / magnification) - srcRect.height);
// create new graphics
try {
display.getProject().getLoader().releaseToFit(g_width * g_height * 10);
}// when closing, asynch state may throw for a null loader.
catch (final Exception e) {
}
// creates a BufferedImage.TYPE_INT_ARGB image in my T60p ATI FireGL laptop
final BufferedImage target = getGraphicsConfiguration().createCompatibleImage(g_width, g_height, Transparency.TRANSLUCENT);
// Utils.log2("offscreen acceleration priority: " + target.getAccelerationPriority());
final Graphics2D g = target.createGraphics();
// at_original);
g.setTransform(atc);
// setRenderingHints(g);
// always a stroke of 1.0, regardless of magnification; the stroke below corrects for that
g.setStroke(stroke);
// Testing: removed Area.subtract, now need to fill in background
g.setColor(Color.black);
g.fillRect(0, 0, g_width - r1.x, g_height - r2.y);
// paint:
// 1 - background
// 2 - images and anything else not on al_top
// 3 - non-srcRect areas
// Utils.log2("offscreen painting: " + al_paint.size());
// filter paintables
final Collection<? extends Paintable> paintables = graphics_source.asPaintable(al_paint);
// adjust:
first_non_patch = paintables.size() - (al_paint.size() - first_non_patch);
// Determine painting mode
if (Display.REPAINT_SINGLE_LAYER == mode) {
if (display.isLiveFilteringEnabled()) {
paintWithFiltering(g, al_paint, paintables, first_non_patch, g_width, g_height, active, c_alphas, active_layer, layers, true);
} else {
// Direct painting mode, with prePaint abilities
int i = 0;
for (final Paintable d : paintables) {
if (i == first_non_patch) {
// Object antialias = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
// to smooth edges of the images
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Object text_antialias = g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Object render_quality = g.getRenderingHint(RenderingHints.KEY_RENDERING);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
}
if (prepaint)
d.prePaint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
else
d.paint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
i++;
}
}
} else if (Display.REPAINT_MULTI_LAYER == mode) {
// With prePaint capabilities:
if (display.isLiveFilteringEnabled()) {
paintWithFiltering(g, al_paint, paintables, first_non_patch, g_width, g_height, active, c_alphas, active_layer, layers, false);
} else {
int i = 0;
if (prepaint) {
for (final Paintable d : paintables) {
if (first_non_patch == i)
break;
d.prePaint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
i++;
}
} else {
for (final Paintable d : paintables) {
if (first_non_patch == i)
break;
d.paint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
i++;
}
}
}
// then blend on top the ImageData of the others, in reverse Z order and using the alpha of the LayerPanel
final Composite original = g.getComposite();
// reset
g.setTransform(new AffineTransform());
// Paint what:
final Set<Class<?>> included = display.classes_to_multipaint;
for (final ListIterator<LayerPanel> it = blending_list.listIterator(blending_list.size()); it.hasPrevious(); ) {
final LayerPanel lp = it.previous();
if (lp.layer == active_layer)
continue;
active_layer.getProject().getLoader().releaseToFit(g_width * g_height * 4 + 1024);
final BufferedImage bi = getGraphicsConfiguration().createCompatibleImage(g_width, g_height, Transparency.TRANSLUCENT);
final Graphics2D gb = bi.createGraphics();
gb.setTransform(atc);
for (final Displayable d : lp.layer.find(srcRect, true)) {
if (included.contains(d.getClass()))
// not prePaint! We want direct painting, even if potentially slow
d.paint(gb, srcRect, magnification, false, c_alphas, lp.layer, layers);
}
// Repeating loop ... the human compiler at work, just because one cannot lazily concatenate both sequences:
for (final Displayable d : lp.layer.getParent().roughlyFindZDisplayables(lp.layer, srcRect, true)) {
if (included.contains(d.getClass()))
// not prePaint! We want direct painting, even if potentially slow
d.paint(gb, srcRect, magnification, false, c_alphas, lp.layer, layers);
}
try {
g.setComposite(Displayable.getComposite(display.getLayerCompositeMode(lp.layer), lp.getAlpha()));
g.drawImage(display.applyFilters(bi), 0, 0, null);
} catch (final Throwable t) {
Utils.log("Could not use composite mode for layer overlays! Your graphics card may not support it.");
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, lp.getAlpha()));
g.drawImage(bi, 0, 0, null);
IJError.print(t);
}
bi.flush();
}
// restore
g.setComposite(original);
g.setTransform(atc);
// then paint the non-Patch objects of the current layer
// Object antialias = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
// to smooth edges of the images
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Object text_antialias = g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Object render_quality = g.getRenderingHint(RenderingHints.KEY_RENDERING);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// For the current layer:
for (int i = first_non_patch; i < al_paint.size(); i++) {
final Displayable d = al_paint.get(i);
d.paint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
}
} else if (Display.REPAINT_RGB_LAYER == mode) {
// TODO rewrite to avoid calling the list twice
final Collection<? extends Paintable> paintable_patches = graphics_source.asPaintable(al_paint);
//
final HashMap<Color, byte[]> channels = new HashMap<Color, byte[]>();
hm.put(Color.green, active_layer);
for (final Map.Entry<Color, Layer> e : hm.entrySet()) {
// INDEXED, Loader.GRAY_LUT);
final BufferedImage bi = new BufferedImage(g_width, g_height, BufferedImage.TYPE_BYTE_GRAY);
final Graphics2D gb = bi.createGraphics();
gb.setTransform(atc);
final Layer la = e.getValue();
final ArrayList<Paintable> list = new ArrayList<Paintable>();
if (la == active_layer) {
// don't paint current layer in two channels
if (Color.green != e.getKey())
continue;
list.addAll(paintable_patches);
} else {
list.addAll(la.find(Patch.class, srcRect, true));
}
// Stack.class and perhaps others
list.addAll(la.getParent().getZDisplayables(ImageData.class, true));
for (final Paintable d : list) {
d.paint(gb, srcRect, magnification, false, c_alphas, la, layers);
}
channels.put(e.getKey(), (byte[]) new ByteProcessor(bi).getPixels());
}
final byte[] red, green, blue;
green = channels.get(Color.green);
if (null == channels.get(Color.red))
red = new byte[green.length];
else
red = channels.get(Color.red);
if (null == channels.get(Color.blue))
blue = new byte[green.length];
else
blue = channels.get(Color.blue);
final int[] pix = new int[green.length];
for (int i = 0; i < green.length; i++) {
pix[i] = ((red[i] & 0xff) << 16) + ((green[i] & 0xff) << 8) + (blue[i] & 0xff);
}
// undo transform, is intended for Displayable objects
g.setTransform(new AffineTransform());
final ColorProcessor cp = new ColorProcessor(g_width, g_height, pix);
if (display.invert_colors)
cp.invert();
display.applyFilters(cp);
final Image img = cp.createImage();
g.drawImage(img, 0, 0, null);
img.flush();
// reset
g.setTransform(atc);
// then paint the non-Image objects of the current layer
// Object antialias = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
// to smooth edges of the images
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Object text_antialias = g.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Object render_quality = g.getRenderingHint(RenderingHints.KEY_RENDERING);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
for (final Displayable d : al_paint) {
if (ImageData.class.isInstance(d))
continue;
d.paint(g, srcRect, magnification, d == active, c_alphas, active_layer, layers);
}
// TODO having each object type in a key/list<type> table would be so much easier and likely performant.
}
// finally, paint non-srcRect areas
if (r1.width > 0 || r1.height > 0 || r2.width > 0 || r2.height > 0) {
g.setColor(Color.gray);
g.setClip(r1);
g.fill(r1);
g.setClip(r2);
g.fill(r2);
}
return target;
} catch (final OutOfMemoryError oome) {
// so OutOfMemoryError won't generate locks
IJError.print(oome);
} catch (final Exception e) {
IJError.print(e);
}
return null;
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class Patch method maskBorder.
/**
* Make the border have an alpha of zero.
*/
public boolean maskBorder(final int left, final int top, final int right, final int bottom) {
final int w = o_width - right - left;
final int h = o_height - top - bottom;
if (w < 0 || h < 0 || left > o_width || top > o_height) {
Utils.log("Cannot cut border for patch " + this + " : border off image bounds.");
return false;
}
try {
ByteProcessor bp = getAlphaMask();
if (null == bp) {
bp = new ByteProcessor(o_width, o_height);
bp.setRoi(new Roi(left, top, w, h));
bp.setValue(255);
bp.fill();
} else {
// make borders black
bp.setValue(0);
for (final Roi r : new Roi[] { new Roi(0, 0, o_width, top), new Roi(0, top, left, o_height - top - bottom), new Roi(0, o_height - bottom, o_width, bottom), new Roi(o_width - right, top, right, o_height - top - bottom) }) {
bp.setRoi(r);
bp.fill();
}
}
setAlphaMask(bp);
} catch (final Exception e) {
IJError.print(e);
return false;
}
return true;
}
Aggregations