Hi all, here's an open copy of a letter I sent to Wayne Rasband. Honestly I
don't follow the mailing list (no time), and some of this may all be outdated... but maybe not. Anyway here's the letter. It includes a link to my code. Dear Wayne Rasband, I have emailed in the past (in 2005) about some work I had done with ImageJ. Specifically I had written a class and an API. We had corresponded about these briefly (see below). I have never gotten to working on this further, as I started a Neurology residency. However, I have recently been approached by people who are starting to use what I had made, so I got around to cleaning things up a little. There is now a website describing ImageOverlay, Census, and a few of my other ImageJ projects. http://www.masny.dk/imagej/index.php I feel ImageOverlay and Census are especially useful tools, not just for me, but for others. If you wouldn't mind, take a peek at them. I'll likely submit the link to the mailing list sometime soon. A summary: 1) ImageOverlay class: a simple addition to ImagePlus. It represents an overlay to be rendered on top of the actual data image (transparent at default), to be used by interfaces. The intent is to allow markings on the picture presented to the viewer, while not editing the underlying actual image. 2) "Census": It is actually more of an API. At its most basic it is a simple image counting tool, which uses the ImageOverlay to mark where on the image a count had been made. It also however has a simplified self-compiling plugin structure which should allow a user to redefine how the image is processed after each count. This works but still has some bugs and unfinished components (wand, autofind). Also, I still would favor incorporating the ImageOverlay into the main tree, for interface writers like myself... :) Thank you for all your work, Peter Sebastian Masny |
Hi,
On Fri, 23 Jan 2009, Peter Sebastian Masny wrote: > 1) ImageOverlay class: a simple addition to ImagePlus. It represents an > overlay to be rendered on top of the actual data image (transparent > at default), to be used by interfaces. The intent is to allow > markings on the picture presented to the viewer, while not editing > the underlying actual image. As Samuel demonstrated, it is possible (and actually a cleaner design IMHO) to do this outside of ImageJ, in the plugin. However, apart from the overuse of the word "stupid" and the erroneous assumption that ImageJ is licensed under the GPL, Samuel's code still has a shortcoming: you do not need to override ImagePlus at all, just overriding ImageCanvas is plenty enough. Ciao, Dscho |
Johannes Schindelin wrote:
> As Samuel demonstrated, it is possible (and actually a cleaner design > IMHO) to do this outside of ImageJ, in the plugin. > > However ... you do not need to override ImagePlus at all, just > overriding ImageCanvas is plenty enough. > > Ciao, > Dscho > Hi all, Wayne Rasband wrote an email as well, with the same message. I can't use just the roi of setDisplayList, so I took on the challenge of writing an ImageCanvas extension. However, it doesn't work. It runs, but nothing happens. Any sage advice on why would be greatly appreciated Thanks, Peter The extended class: package ij_ImageCanvasWithOverlay; import ij.ImagePlus; import ij.IJ; import ij.gui.ImageCanvas; import java.awt.*; import java.awt.image.*; /* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * * Peter Sebastian Masny * * Parts of this code were adapted from Wayne Rasband, Sergio * Caballero Jr., Michael A. Miller, Philippe Thevenaz, and * Samuel Moll. Content derived from these authors follow their * corresponding copyrights. * * @version 2.0 26 Jan 2009 * @author Peter Sebastian Masny */ public class ImageCanvasWithOverlay extends ImageCanvas { boolean overlayDisplay = true; protected MemoryImageSource overlaySource; protected ColorModel overlayCm; protected int[] overlayPixels; // 32-bit protected Image overlayImg; public ImageCanvasWithOverlay(ImagePlus imp) { super(imp); overlayCm = ColorModel.getRGBdefault(); overlayPixels = new int[imageWidth * imageHeight]; overlaySource = new MemoryImageSource(imageWidth, imageHeight, overlayCm, overlayPixels, 0, imageWidth); overlaySource.setAnimated(true); overlaySource.setFullBufferUpdates(true); overlayImg = Toolkit.getDefaultToolkit().createImage(overlaySource); } public void overlayHide() { overlayDisplay = true; } public void overlayShow() { overlayDisplay = false; } @Override public void paint(Graphics g) { super.paint(g); try { if (overlayDisplay) { g.drawImage(overlayImg, 0, 0, (int) (srcRect.width * magnification), (int) (srcRect.height * magnification), srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, null); } } catch (OutOfMemoryError e) { IJ.outOfMemory("Paint"); } } public void overlaySetPixel(int x, int y, int i) { if ((x >= 0) && (y >= 0) && (x < imageWidth) && (y < imageHeight)) { overlayPixels[x + imageWidth * y] = i; } } public void overlaySetLine(int x1, int y1, int x2, int y2, int i) { int dx = x2 - x1; int dy = y2 - y1; int absdx = dx >= 0 ? dx : -dx; int absdy = dy >= 0 ? dy : -dy; int n = absdy > absdx ? absdy : absdx; double xinc = (double) dx / n; double yinc = (double) dy / n; n++; double x = x1 < 0 ? x1 - 0.5 : x1 + 0.5; double y = y1 < 0 ? y1 - 0.5 : y1 + 0.5; do { overlaySetPixel((int) x, (int) y, i); x += xinc; y += yinc; } while (--n > 0); } } The test plugin: import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; import ij_ImageCanvasWithOverlay.ImageCanvasWithOverlay; /* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * * Peter Sebastian Masny * * Parts of this code were adapted from Wayne Rasband, Sergio * Caballero Jr., Michael A. Miller, Philippe Thevenaz, and * Samuel Moll. Content derived from these authors follow their * corresponding copyrights. * * @version 2.0 26 Jan 2009 * @author Peter Sebastian Masny */ public class newOverlay_Test implements PlugIn { public void run(String arg) { ImagePlus imp = WindowManager.getCurrentImage(); ImageCanvasWithOverlay icwo = new ImageCanvasWithOverlay(imp); for (int i = 10; i < 20; i++) { icwo.overlaySetPixel(15, i, 0x77ff0000); } icwo.overlaySetLine(10, 15, 20, 15, 0xff00ff00); icwo.repaint(); } } |
Hi,
On Mon, 26 Jan 2009, Peter Sebastian Masny wrote: > Wayne Rasband wrote an email as well, with the same message. I can't use > just the roi of setDisplayList, so I took on the challenge of writing an > ImageCanvas extension. Right, the DisplayList only displays ROIs. > The extended class: > > package ij_ImageCanvasWithOverlay; > > import ij.ImagePlus; > import ij.IJ; > import ij.gui.ImageCanvas; > import java.awt.*; > import java.awt.image.*; > > /* > * * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Lesser General Public > * License as published by the Free Software Foundation; either > * version 2.1 of the License, or (at your option) any later version. > * > * This library is distributed in the hope that it will be useful, > * but WITHOUT ANY WARRANTY; without even the implied warranty of > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > * Lesser General Public License for more details. > * > * You should have received a copy of the GNU Lesser General Public > * License along with this library; if not, write to the Free Software > * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 > * USA > * > * > * Peter Sebastian Masny > * > * Parts of this code were adapted from Wayne Rasband, Sergio > * Caballero Jr., Michael A. Miller, Philippe Thevenaz, and > * Samuel Moll. Content derived from these authors follow their > * corresponding copyrights. > * > * @version 2.0 26 Jan 2009 > * @author Peter Sebastian Masny > */ > > public class ImageCanvasWithOverlay extends ImageCanvas { > > boolean overlayDisplay = true; > protected MemoryImageSource overlaySource; > protected ColorModel overlayCm; > protected int[] overlayPixels; // 32-bit > protected Image overlayImg; > > public ImageCanvasWithOverlay(ImagePlus imp) { > super(imp); > overlayCm = ColorModel.getRGBdefault(); > overlayPixels = new int[imageWidth * imageHeight]; > overlaySource = new MemoryImageSource(imageWidth, imageHeight, > overlayCm, overlayPixels, 0, imageWidth); > overlaySource.setAnimated(true); > overlaySource.setFullBufferUpdates(true); > overlayImg = Toolkit.getDefaultToolkit().createImage(overlaySource); > } > > public void overlayHide() { > overlayDisplay = true; > } > > public void overlayShow() { > overlayDisplay = false; > } Is this not the wrong way round? overlayHide() should set it to false, and overlayShow() should set it to true? > public void overlaySetPixel(int x, int y, int i) { > if ((x >= 0) && (y >= 0) && (x < imageWidth) && (y < imageHeight)) { > overlayPixels[x + imageWidth * y] = i; > } > } > > public void overlaySetLine(int x1, int y1, int x2, int y2, int i) { > [...] If you would create a BufferedImage instead of a MemoryImageSource, you could use the getGraphics method of that instance and do many more things than just set a pixel or a line. Note: I did not have time to test/debug your code yet. Ciao, Dscho |
In reply to this post by Peter Sebastian Masny
Hi,
On Mon, 26 Jan 2009, Peter Sebastian Masny wrote: > Wayne Rasband wrote an email as well, with the same message. I can't use > just the roi of setDisplayList, so I took on the challenge of writing an > ImageCanvas extension. > > However, it doesn't work. It runs, but nothing happens. Any sage advice > on why would be greatly appreciated The culprit is that you only constructed the ImageCanvasWithOverlay, but did not show it. You need to insert this line just before the repaint() call: imp.setWindow(new ImageWindow(imp, icwo)); Hth, Dscho |
In reply to this post by dscho
Hi,
On Mon, 26 Jan 2009, Johannes Schindelin wrote: > > Peter wrote: > > > public void overlaySetPixel(int x, int y, int i) { > > if ((x >= 0) && (y >= 0) && (x < imageWidth) && (y < imageHeight)) { > > overlayPixels[x + imageWidth * y] = i; > > } > > } > > > > public void overlaySetLine(int x1, int y1, int x2, int y2, int i) { > > [...] > > If you would create a BufferedImage instead of a MemoryImageSource, you > could use the getGraphics method of that instance and do many more things > than just set a pixel or a line. In other words, something like this: -- snipsnap -- import ij.IJ; import ij.ImagePlus; import ij.gui.ImageCanvas; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; /* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * * Peter Sebastian Masny * * Parts of this code were adapted from Wayne Rasband, Sergio * Caballero Jr., Michael A. Miller, Philippe Thevenaz, and * Samuel Moll. Content derived from these authors follow their * corresponding copyrights. * * @version 2.0 26 Jan 2009 * @author Peter Sebastian Masny */ public class ImageCanvasWithOverlay extends ImageCanvas { boolean overlayDisplay = true; protected BufferedImage overlay; public ImageCanvasWithOverlay(ImagePlus imp) { super(imp); overlay = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); } public void overlayHide() { overlayDisplay = true; } public void overlayShow() { overlayDisplay = false; } @Override public void paint(Graphics g) { super.paint(g); try { if (overlayDisplay) { g.drawImage(overlay, 0, 0, (int) (srcRect.width * magnification), (int) (srcRect.height * magnification), srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, null); } } catch (OutOfMemoryError e) { IJ.outOfMemory("Paint"); } } public Graphics getGraphics(int color) { Graphics graphics = overlay.getGraphics(); graphics.setColor(new Color(color)); return graphics; } public void overlaySetPixel(int x, int y, int i) { getGraphics(i).drawRect(x, y, 1, 1); } public void overlaySetLine(int x1, int y1, int x2, int y2, int i) { getGraphics(i).drawLine(x1, y1, x2, y2); } } |
Johannes Schindelin wrote:
> Hi, > > On Mon, 26 Jan 2009, Johannes Schindelin wrote: > >> If you would create a BufferedImage instead of a MemoryImageSource, you >> could use the getGraphics method of that instance and do many more things >> than just set a pixel or a line. >> > > In other words, something like this: > > -- snipsnap -- > Thank you.. The code is very clean now, and it works!!! I made a minor change and took the Color definition out of the class, to make it more flexible. The final code is below. Now to fix Census to work with this structure... should be quick. Thank you again for the help. It is much better now. Peter package ij_ImageCanvasWithOverlay; import ij.ImagePlus; import ij.IJ; import ij.gui.ImageCanvas; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; /* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * * Peter Sebastian Masny * [hidden email] * * Parts of this code were adapted from Wayne Rasband, Sergio * Caballero Jr., Michael A. Miller, Philippe Thevenaz, * Samuel Moll, and Johannes Schindelin. Content derived from * these authors follow their corresponding copyrights. * * @version 2.1 26 Jan 2009 * @author Peter Sebastian Masny */ public class ImageCanvasWithOverlay extends ImageCanvas { boolean overlayDisplay = true; protected BufferedImage overlay; public ImageCanvasWithOverlay(ImagePlus imp) { super(imp); overlay = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); } public void overlayHide() { overlayDisplay = false; } public void overlayShow() { overlayDisplay = true; } @Override public void paint(Graphics g) { super.paint(g); if (overlayDisplay) { g.drawImage(overlay, 0, 0, (int) (srcRect.width * magnification), (int) (srcRect.height * magnification), srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, null); } } public Graphics getColoredGraphics(Color color) { Graphics graphics = overlay.getGraphics(); graphics.setColor(color); return graphics; } public void overlaySetPixel(int x, int y, Color c) { getColoredGraphics(c).drawRect(x, y, 1, 1); } public void overlaySetLine(int x1, int y1, int x2, int y2, Color c) { getColoredGraphics(c).drawLine(x1, y1, x2, y2); } } Sample plugin using the class: import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; import ij_ImageCanvasWithOverlay.ImageCanvasWithOverlay; /* * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * * Peter Sebastian Masny * [hidden email] * * Parts of this code were adapted from Wayne Rasband, Sergio * Caballero Jr., Michael A. Miller, Philippe Thevenaz, * Samuel Moll, and Johannes Schindelin. Content derived from * these authors follow their corresponding copyrights. * * @version 2.1 26 Jan 2009 * @author Peter Sebastian Masny */ public class newOverlay_Test implements PlugIn { public void run(String arg) { ImagePlus imp = WindowManager.getCurrentImage(); ImageCanvasWithOverlay icwo = new ImageCanvasWithOverlay(imp); imp.setWindow(new ImageWindow(imp, icwo)); for (int i = 10; i < 20; i++) { icwo.overlaySetPixel(15, i, new Color(255,0,0,128)); } icwo.overlaySetLine(10, 15, 20, 15, new Color(0,0,255)); icwo.repaint(); } } |
OK, the website should be up to date. Go to the website at your
discretion for a description of the now easy to use ImageCanvas WithOverlay class, or for the very powerful Census plugin. (Max_XYZ_Project is pretty cool too) http://ps.masny.dk/imagej/index.php Thanks for the help in getting these where they are. Peter |
Free forum by Nabble | Edit this page |