Plugin for Image Fullscreening

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Plugin for Image Fullscreening

Suarez, Ivan *
Dear All:

        My name is Ivan Suarez. I am an employee of the U.S. Food and Drug Administration (FDA), and my colleagues and I want to display DICOM Images in ImageJ in fullscreen mode in a pair of high resolution monitors. Essentially what we want is to not only to display them on the monitors but also be able to change image parameters (i.e. window/level), and do measurements using the ImageJ tools while the images are displayed in the high resolution monitors. The  following are some specifications of the monitors we are using:
-2 Monitors Barco Coronis 5MP Mammography LCD displays (2560 x 2048) graysacle 21" high bright flat panel display.

        I found a MATLAB function for fullscreening written in Java, that I was hoping could be converted into an ImageJ plugin with the specifications I mentioned above:

function fullscreen(image,device_number)
%FULLSCREEN Display fullscreen true colour images
%   FULLSCREEN(C,N) displays matlab image matrix C on
%   display number N (which ranges from 1 to number of screens). Image
%   matrix C must be the exact resolution of the output screen since no
%   scaling in implemented. If fullscreen is activated on the same display
%   as the MATLAB window, use ALT-TAB to switch back.
%
%   If FULLSCREEN(C,N) is called the second time, the screen will update
%   with the new image.
%
%   Use CLOSESCREEN() to exit fullscreen.
%
%   Requires Matlab 7.x (uses Java Virtual Machine), and has been tested on
%   Linux and Windows platforms.
%
%   Written by Pithawat Vachiramon 18/5/2006


ge = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
gds = ge.getScreenDevices();
height = gds(device_number).getDisplayMode().getHeight();
width = gds(device_number).getDisplayMode().getWidth();

global frame_java;
global icon_java;
global device_number_java;

if ~isequal(device_number_java, device_number)
    try frame_java.dispose(); end
    frame_java = [];
    device_number_java = device_number;
end

if ~isequal(class(frame_java), 'javax.swing.JFrame')
    frame_java = javax.swing.JFrame(gds(device_number).getDefaultConfiguration());
    frame_java.setUndecorated(true);
    icon_java = javax.swing.ImageIcon(im2java(image));
    label = javax.swing.JLabel(icon_java);
    frame_java.getContentPane.add(label);
    gds(device_number).setFullScreenWindow(frame_java);
else
    icon_java.setImage(im2java(image));
end
frame_java.pack
frame_java.repaint
frame_java.show

We also don't wanna have limittations on the size of the image and whether it's 8bit or 16bit. Does anyone have a plugin that does something similar. Or could someone help me turn this code into a plugin?

Thank you,

Ivan Suarez
Graduate Research Assistant
U.S. Food and Drug Administration
Reply | Threaded
Open this post in threaded view
|

Re: Plugin for Image Fullscreening

dscho
Hi,

sorry for my late reply...

On Tue, 8 Feb 2011, Suarez, Ivan * wrote:

> Or could someone help me turn this code into a plugin?

You might be interested in this code which I wrote for fun a while ago. I
wrote it in the Fiji Script Editor, but as far as I can see, it should run
in ImageJ just as well:

-- snipsnap --
import ij.IJ;
import ij.ImagePlus;
import ij.WindowManager;

import ij.plugin.PlugIn;

import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Toolkit;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Fiji_Presenter extends Frame implements PlugIn {
        protected Image image;
        protected int imageWidth, imageHeight;
       
        protected int currentImageIndex;
        protected ImageProcessor[] images;
        protected Transformation[] transforms;
        protected Panel imagePanel;

        public Fiji_Presenter() {
                super("Fullscreen Fiji Presenter");
                setUndecorated(true);

                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                imagePanel = new Panel() {
                        public void update(Graphics g) {
                                paint(g);
                        }

                        public void paint(Graphics g) {
                                int panelW = getWidth(), panelH = getHeight();
                                if (panelW == 0 || panelH == 0)
                                        return;
                                Image image = getCurrentImage();
                                Transformation transform = getCurrentTransformation();
                                int w = (int)(imageWidth * transform.magnification);
                                int h = (int)(imageHeight * transform.magnification);
                                if (transform.x > 0)
                                        g.fillRect(0, 0, transform.x, panelH);
                                if (transform.y > 0)
                                        g.fillRect(0, 0, panelW, transform.y);
                                if (transform.x + w < panelW)
                                        g.fillRect(transform.x + w, 0, panelW - transform.x - w, panelH);
                                if (transform.y + h < panelH)
                                        g.fillRect(0, transform.y + h, panelW, panelH - transform.y - h);
                                g.drawImage(image, transform.x, transform.y, w, h, null);
                        }
                };
                imagePanel.setSize(screenSize);
                imagePanel.setMinimumSize(screenSize);
                imagePanel.setBackground(Color.WHITE);
                KeyAdapter listener = new KeyAdapter() {
                        public void keyPressed(KeyEvent e) {
                                Fiji_Presenter.this.keyPressed(e);
                        }
                };
                imagePanel.addKeyListener(listener);
                add(imagePanel);
                pack();
                setExtendedState(Frame.MAXIMIZED_BOTH);
                addKeyListener(listener);
        }

        public void run(String arg) {
                int[] imageIDs = WindowManager.getIDList();
                ImageProcessor[] images = new ImageProcessor[imageIDs.length];
                for (int i = 0; i < images.length; i++)
                        images[i] = WindowManager.getImage(imageIDs[i]).getProcessor();
                init(images);
                setVisible(true);
        }

        public void init(ImageProcessor[] images) {
                this.images = images;
                transforms = new Transformation[images.length];
        }

        public Image getCurrentImage() {
                if (image == null) {
                        image = images[currentImageIndex].getBufferedImage();
                        imageWidth = images[currentImageIndex].getWidth();
                        imageHeight = images[currentImageIndex].getHeight();
                }
                return image;
        }

        public Transformation getCurrentTransformation() {
                if (transforms[currentImageIndex] == null)
                        transforms[currentImageIndex] = new Transformation();
                return transforms[currentImageIndex];
        }

        public void setImageIndex(int i) {
                currentImageIndex = Math.max(0, Math.min(images.length - 1, i));
                image = null;
        }

        public void nextImage() {
                setImageIndex(currentImageIndex + 1);
        }

        public void previousImage() {
                setImageIndex(currentImageIndex - 1);
        }

        public void setVisible(boolean flag) {
                // TODO: may depend on screen
                GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice device = env.getDefaultScreenDevice();
                if (device.isFullScreenSupported())
                        device.setFullScreenWindow(this);

                WindowManager.addWindow(this);
                super.setVisible(flag);
                requestFocus();
        }

        public void keyPressed(KeyEvent e) {
                switch (e.getKeyCode()) {
                case KeyEvent.VK_ENTER:
                        IJ.getInstance().requestFocus();
                        break;
                case KeyEvent.VK_ESCAPE:
                case KeyEvent.VK_W:
                        WindowManager.removeWindow(this);
                        dispose();
                        break;
                case KeyEvent.VK_SPACE:
                        nextImage();
                        repaintPanel();
                        break;
                case KeyEvent.VK_BACK_SPACE:
                        previousImage();
                        repaintPanel();
                        break;
                case KeyEvent.VK_PLUS:
                case KeyEvent.VK_MINUS:
                        transforms[currentImageIndex].zoom(e.getKeyCode() == e.VK_PLUS);
                        repaintPanel();
                        break;
                case KeyEvent.VK_LEFT:
                case KeyEvent.VK_RIGHT:
                        transforms[currentImageIndex].pan(e.getKeyCode() == e.VK_LEFT ? 1 : -1, 0);
                        repaintPanel();
                        break;
                case KeyEvent.VK_UP:
                case KeyEvent.VK_DOWN:
                        transforms[currentImageIndex].pan(0, e.getKeyCode() == e.VK_UP ? 1 : -1);
                        repaintPanel();
                        break;
                default:
                        switch (e.getKeyChar()) {
                        case '1':
                                transforms[currentImageIndex].reset(images[currentImageIndex]);
                                repaintPanel();
                                break;
                        case '+':
                        case '=':
                        case '-':
                                transforms[currentImageIndex].zoom(e.getKeyChar() != '-');
                                repaintPanel();
                                break;
                        default:
                                System.err.println("Ignoring unknown keycode: " + e);
                        }
                }
        }

        public void repaintPanel() {
                imagePanel.repaint();
        }

        protected class Transformation {
                protected int x, y;
                protected double magnification;
                protected final double ZOOM_STEP = 1.25;
                protected final double PAN_STEP = 0.2; // relative to the width / height

                public Transformation(int x, int y, double magnification) {
                        this.x = x;
                        this.y = y;
                        this.magnification = magnification;
                }

                public Transformation() {
                        this(images[currentImageIndex]);
                }

                public Transformation(ImageProcessor ip) {
                        reset(ip);
                }

                public void reset(ImageProcessor ip) {
                        int imageWidth = ip.getWidth(), imageHeight = ip.getHeight();
                        if (imageWidth == 0 || imageHeight == 0) {
                                magnification = 1;
                                return;
                        }
                        Dimension size = imagePanel.getSize();
                        if (size.width == 0 || size.height == 0) {
                                magnification = 1;
                                return;
                        }
                        if (imageWidth <= size.width && imageHeight <= size.height) {
                                magnification = 1;
                                x = (size.width - imageWidth) / 2;
                                y = (size.height - imageHeight) / 2;
                        } else if (imageWidth * size.height > imageHeight * size.width) {
                                magnification = size.width / (double)imageWidth;
                                y = (int)((size.height - imageHeight * magnification) / 2);
                        }
                        else {
                                magnification = size.height / (double)imageHeight;
                                x = (int)((size.width - imageWidth * magnification) / 2);
                        }
                }

                public void zoom(boolean in) {
                        Dimension size = imagePanel.getSize();
                        zoom(in, size.width / 2, size.height / 2);
                }

                public void zoom(boolean in, int xCenter, int yCenter) {
                        double u = (xCenter - x) / magnification;
                        double v = (yCenter - y) / magnification;
                        magnification *= in ? ZOOM_STEP : 1 / ZOOM_STEP;
                        x = (int)(xCenter - u * magnification);
                        y = (int)(yCenter - v * magnification);
                }

                public void pan(int xStep, int yStep) {
                        Dimension size = imagePanel.getSize();
                        x -= (int)(xStep * size.width * PAN_STEP);
                        y -= (int)(yStep * size.height * PAN_STEP);
                }
        }
}
Reply | Threaded
Open this post in threaded view
|

Re: Plugin for Image Fullscreening

dscho
Hi,

On Wed, 9 Feb 2011, Johannes Schindelin wrote:

> public void setVisible(boolean flag) {
> [...]
> WindowManager.addWindow(this);

... and of course I managed to forget the counterpart to adding the
presenter window to the WindowManager. Maybe you can add that? It should
be in the windowClosed() method.

Ciao,
Dscho
Reply | Threaded
Open this post in threaded view
|

Re: Plugin for Image Fullscreening

dscho
Hi,

On Thu, 10 Feb 2011, Suarez, Ivan * wrote:

> Thank you for your response. However, I am new to ImageJ, so could you
> tell me how to implement the code you sent me into ImageJ?

You probably did not mean "implement", since I have done that already, but
"run" instead, correct? Try Plugins>Compile and Run...

Ciao,
Johannes
Reply | Threaded
Open this post in threaded view
|

Re: Plugin for Image Fullscreening

dscho
In reply to this post by dscho
Dear Ivan,

On Fri, 11 Feb 2011, Suarez, Ivan * wrote:

> The code works well. However, whenever I run the code it fullscreens it
> in the main monitor. We want to display these images in 2 high
> resolution monitors connected to the system. Therefore, I want to be
> able to control which device will the code fullscreen the image on.
> Where in the code can I do this?

As I said, I wrote this for fun, and there are a few shortcomings that I
hope you will fix (and of course provide me with the fixed version).

The code currently uses always the default screen. You would need to find
out what the screen device is which displays the window currently. For
this, I would suggest to study the documentation of AWT and/or ask your
search engine of choice.

Ciao,
Johannes