ImageJ1 has built-in support for non-uniform x/y/z units via Calibration's getX/Y/ZUnit() and setX/Y/ZUnit(). At my company, we look a good amount of "raw" image data that naturally has time as one unit and detectors as the other unit, so our raw file reader makes use of this functionality. I found that some parts of ImageJ don't seem to look for X/Y/Z units, instead using getUnit/s() without checking for non-uniform units.
So, I have put together a patch to improve a couple of key functions. I based the patch on the 2014.06.23 (1.40c20) snapshot on https://github.com/imagej/imagej1.git. I don't see any pull requests for that project, so not sure how the IJ team would want this patch? For now, it is inline, below. But I'm happy to push it to the correct spot ... perhaps I should be asking http://wiki.imagej.net/ImageJA for a pull request? Thanks, Alan >From ad1add8f9dcdfd1ba42436a225a0c41e80353be6 Mon Sep 17 00:00:00 2001 From: Alan Brooks <alancbro...@gmail.com> Date: Wed, 25 Jun 2014 12:21:48 -0500 Subject: [PATCH] Show correct non-matching x & y units on surface plot. --- ij/plugin/SurfacePlotter.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ij/plugin/SurfacePlotter.java b/ij/plugin/SurfacePlotter.java index 011754e..9789155 100644 --- a/ij/plugin/SurfacePlotter.java +++ b/ij/plugin/SurfacePlotter.java @@ -306,12 +306,15 @@ public class SurfacePlotter implements PlugIn { ip2.drawString(s, (int) p1x-18-w, (int) p1y +h/2); //x-axis - s = (double) Math.round(roi.height*cal.pixelHeight*10)/10+" "+cal.getUnits(); + boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit()); + String xunits = unitsMatch ? cal.getUnits() : cal.getYUnit(); // why swapped? + s = (double) Math.round(roi.height*cal.pixelHeight*10)/10+" "+xunits; w = ip2.getFontMetrics().stringWidth(s); drawAxis(ip2, (int) p1x, (int) p1y, (int) p2x, (int) p2y, s, 10, -1, 1, 1); //y-axis - s = (double) Math.round(roi.width*cal.pixelWidth*10)/10+" "+cal.getUnits(); + String yunits = unitsMatch ? cal.getUnits() : cal.getXUnit(); // why swapped? + s = (double) Math.round(roi.width*cal.pixelWidth*10)/10+" "+yunits; w = ip2.getFontMetrics().stringWidth(s); //drawAxis(ip2, (int) p2x, (int) p2y, (int) p3x, (int) p3y, s, 10, 1 , 1, -1); drawAxis(ip2, (int) p2x, (int) p2y, (int) p3x, (int) p3y, s, 10, 1, -1, 1); -- 1.8.4.msysgit.0 >From 70df4ea5619a010caa8732c764ea2ab897dab448 Mon Sep 17 00:00:00 2001 From: Alan Brooks <alancbro...@gmail.com> Date: Wed, 25 Jun 2014 12:20:54 -0500 Subject: [PATCH] Show correct non-matching x & y units when specifying an ROI selection. --- ij/plugin/SpecifyROI.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ij/plugin/SpecifyROI.java b/ij/plugin/SpecifyROI.java index bb48b24..db71ac3 100644 --- a/ij/plugin/SpecifyROI.java +++ b/ij/plugin/SpecifyROI.java @@ -111,8 +111,10 @@ public class SpecifyROI implements PlugIn, DialogListener { gd.addCheckbox("Oval", oval); gd.addCheckbox("Constrain square/circle", square); gd.addCheckbox("Centered",centered); + boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit()); + String units = unitsMatch ? cal.getUnits() : cal.getXUnit()+" x "+cal.getYUnit(); if (cal.scaled()) - gd.addCheckbox("Scaled units ("+cal.getUnits()+")", scaledUnits); + gd.addCheckbox("Scaled units ("+units+")", scaledUnits); fields = gd.getNumericFields(); gd.addDialogListener(this); gd.showDialog(); -- 1.8.4.msysgit.0 >From c8717cd7146dae5e54f6b93ba529632f828ce5ef Mon Sep 17 00:00:00 2001 From: Alan Brooks <alancbro...@gmail.com> Date: Wed, 25 Jun 2014 12:18:12 -0500 Subject: [PATCH] Update Transformer so that Rotate Right and Rotate Left commands preserve non-matching x & y units. --- ij/plugin/filter/Transformer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ij/plugin/filter/Transformer.java b/ij/plugin/filter/Transformer.java index 26a1e96..5a6aa88 100644 --- a/ij/plugin/filter/Transformer.java +++ b/ij/plugin/filter/Transformer.java @@ -62,6 +62,9 @@ public class Transformer implements PlugInFilter { double pixelWidth = cal.pixelWidth; cal.pixelWidth = cal.pixelHeight; cal.pixelHeight = pixelWidth; + String xUnit = cal.getXUnit(); + cal.setXUnit(cal.getYUnit()); + cal.setYUnit(xUnit); return; } } -- 1.8.4.msysgit.0 >From bc4a026a612559b77be7dfc2120886be3529d092 Mon Sep 17 00:00:00 2001 From: Alan Brooks <alancbro...@gmail.com> Date: Wed, 25 Jun 2014 12:16:43 -0500 Subject: [PATCH] Improve ImageWindow's subtitle to handle non-matching x & y units. Useful when working with raw data files. --- ij/gui/ImageWindow.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ij/gui/ImageWindow.java b/ij/gui/ImageWindow.java index a81ebe3..ee853d9 100644 --- a/ij/gui/ImageWindow.java +++ b/ij/gui/ImageWindow.java @@ -301,8 +301,16 @@ public class ImageWindow extends Frame implements FocusListener, WindowListener, int type = imp.getType(); Calibration cal = imp.getCalibration(); if (cal.scaled()) { - s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + "x" + IJ.d2s(imp.getHeight()*cal.pixelHeight,2) - + " " + cal.getUnits() + " (" + imp.getWidth() + "x" + imp.getHeight() + "); "; + boolean unitsMatch = cal.getXUnit().equals(cal.getYUnit()); + if (unitsMatch) { + s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + "x" + + IJ.d2s(imp.getHeight()*cal.pixelHeight,2) + " " + cal.getUnits() + + " (" + imp.getWidth() + "x" + imp.getHeight() + "); "; + } else { + s += IJ.d2s(imp.getWidth()*cal.pixelWidth,2) + cal.getXUnit() + " x " + + IJ.d2s(imp.getHeight()*cal.pixelHeight,2) + cal.getYUnit() + + " (" + imp.getWidth() + "x" + imp.getHeight() + "); "; + } } else s += imp.getWidth() + "x" + imp.getHeight() + " pixels; "; double size = ((double)imp.getWidth()*imp.getHeight()*imp.getStackSize())/1024.0; -- 1.8.4.msysgit.0 >From cb0e1dd0f81ca526cc17de90acc13f1569e06584 Mon Sep 17 00:00:00 2001 From: Alan Brooks <alancbro...@gmail.com> Date: Wed, 25 Jun 2014 12:07:30 -0500 Subject: [PATCH] Respect X/Y/Z units when showing file information. Useful for displaying details about raw data collect files where x-y-z units are often different. --- ij/plugin/filter/Info.java | 59 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/ij/plugin/filter/Info.java b/ij/plugin/filter/Info.java index 9ce1ac2..99fdcf8 100644 --- a/ij/plugin/filter/Info.java +++ b/ij/plugin/filter/Info.java @@ -85,36 +85,37 @@ public class Info implements PlugInFilter { } String getInfo(ImagePlus imp, ImageProcessor ip) { - String s = new String("\n"); - s += "Title: " + imp.getTitle() + "\n"; - Calibration cal = imp.getCalibration(); - int stackSize = imp.getStackSize(); - int channels = imp.getNChannels(); - int slices = imp.getNSlices(); - int frames = imp.getNFrames(); - int digits = imp.getBitDepth()==32?4:0; - int dp, dp2; - if (cal.scaled()) { - String unit = cal.getUnit(); - String units = cal.getUnits(); - double pw = imp.getWidth()*cal.pixelWidth; - double ph = imp.getHeight()*cal.pixelHeight; - dp = Tools.getDecimalPlaces(pw, ph); - s += "Width: "+IJ.d2s(pw,dp)+" " + units+" ("+imp.getWidth()+")\n"; - s += "Height: "+IJ.d2s(ph,dp)+" " + units+" ("+imp.getHeight()+")\n"; - if (slices>1) { - double pd = slices*cal.pixelDepth; - dp = Tools.getDecimalPlaces(pw, pd); - s += "Depth: "+IJ.d2s(pd,dp)+" " + units+" ("+slices+")\n"; - } + String s = new String("\n"); + s += "Title: " + imp.getTitle() + "\n"; + Calibration cal = imp.getCalibration(); + int stackSize = imp.getStackSize(); + int channels = imp.getNChannels(); + int slices = imp.getNSlices(); + int frames = imp.getNFrames(); + int digits = imp.getBitDepth()==32?4:0; + int dp, dp2; + String xunit = cal.getXUnit(); + String yunit = cal.getYUnit(); + String zunit = cal.getZUnit(); + if (cal.scaled()) { + double pw = imp.getWidth()*cal.pixelWidth; + double ph = imp.getHeight()*cal.pixelHeight; + dp = Tools.getDecimalPlaces(pw, ph); + s += "Width: "+IJ.d2s(pw,dp)+" " + xunit +"s ("+imp.getWidth()+")\n"; + s += "Height: "+IJ.d2s(ph,dp)+" " + yunit +"s ("+imp.getHeight()+")\n"; + if (slices>1) { + double pd = slices*cal.pixelDepth; + dp = Tools.getDecimalPlaces(pw, pd); + s += "Depth: "+IJ.d2s(pd,dp)+" " + zunit +"s ("+slices+")\n"; + } double xResolution = 1.0/cal.pixelWidth; double yResolution = 1.0/cal.pixelHeight; int places = Tools.getDecimalPlaces(xResolution, yResolution); if (xResolution==yResolution) - s += "Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+unit+"\n"; + s += "Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+xunit+"\n"; else { - s += "X Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+unit+"\n"; - s += "Y Resolution: "+IJ.d2s(yResolution,places) + " pixels per "+unit+"\n"; + s += "X Resolution: "+IJ.d2s(xResolution,places) + " pixels per "+xunit+"\n"; + s += "Y Resolution: "+IJ.d2s(yResolution,places) + " pixels per "+yunit+"\n"; } } else { s += "Width: " + imp.getWidth() + " pixels\n"; @@ -122,19 +123,19 @@ public class Info implements PlugInFilter { if (stackSize>1) s += "Depth: " + slices + " pixels\n"; } - if (stackSize>1) { + if (stackSize>1) { dp = Tools.getDecimalPlaces(cal.pixelWidth, cal.pixelDepth); - s += "Voxel size: "+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+"x"+IJ.d2s(cal.pixelDepth,dp)+" "+cal.getUnit()+"\n"; + s += "Voxel size: "+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+"x"+IJ.d2s(cal.pixelDepth,dp)+" ("+xunit+" x "+yunit+" x "+zunit+")\n"; } else { dp = Tools.getDecimalPlaces(cal.pixelWidth, cal.pixelHeight); - s += "Pixel size: "+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+" "+cal.getUnit()+"\n"; + s += "Pixel size: "+IJ.d2s(cal.pixelWidth,dp)+"x"+IJ.d2s(cal.pixelHeight,dp)+" ("+xunit+" x "+yunit+")\n"; } s += "ID: "+imp.getID()+"\n"; String zOrigin = stackSize>1||cal.zOrigin!=0.0?","+d2s(cal.zOrigin):""; s += "Coordinate origin: " + d2s(cal.xOrigin)+","+d2s(cal.yOrigin)+zOrigin+"\n"; int type = imp.getType(); - switch (type) { + switch (type) { case ImagePlus.GRAY8: s += "Bits per pixel: 8 "; String lut = "LUT"; -- 1.8.4.msysgit.0
_______________________________________________ ImageJ-devel mailing list ImageJ-devel@imagej.net http://imagej.net/mailman/listinfo/imagej-devel