Initial commit of the ImageJ ZeroMQ Viewer

This commit is contained in:
ebner 2013-04-05 11:08:44 +02:00
commit 65ab9dcca7
10 changed files with 260 additions and 0 deletions

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

1
ch.psi.imagej.zeromq/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ch.psi.imagej.zeromq</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.5

View File

@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.psi</groupId>
<artifactId>ch.psi.imagej.zeromq</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.jeromq</groupId>
<artifactId>jeromq</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>gov.nih.imagej</groupId>
<artifactId>imagej</artifactId>
<version>1.46</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,168 @@
package ch.psi.imagej.zeromq;
// EPICS_AD_Viewer.java
// Original authors
// Tim Madden, APS
// Mark Rivers, University of Chicago
import ij.*;
import ij.process.*;
import java.awt.*;
import ij.plugin.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.border.*;
import org.jeromq.ZMQ;
public class ZeroMQViewer implements PlugIn {
private static final Logger logger = Logger.getLogger(ZeroMQViewer.class.getName());
private ImagePlus img;
private int imageSizeX = 2560;
private int imageSizeY = 2160;
// These are used for the frames/second calculation
private long prevTime;
private int numImageUpdates;
private JFrame frame;
private JTextField fpsText;
private boolean isPluginRunning;
private Timer timer;
private ZMQ.Context context;
private ZMQ.Socket socket;
public void run(String arg) {
IJ.showStatus("Running ZeroMQ Viewer");
try {
isPluginRunning = true;
prevTime = System.currentTimeMillis();
numImageUpdates = 0;
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
context = ZMQ.context(1);
socket = context.socket(ZMQ.PULL);
socket.bind("tcp://*:8080");
while (isPluginRunning) {
byte[] message = socket.recv();
byte[] content = null;
if (socket.hasReceiveMore()) {
content = socket.recv();
}
logger.info(new String(message));
updateImage(content);
}
timer.stop();
socket.close();
context.term();
img.close();
frame.setVisible(false);
IJ.showStatus("Exiting ZeroMQ Viewer");
} catch (Exception e) {
logger.log(Level.SEVERE, "", e);
IJ.showStatus(e.toString());
}
}
public void updateImage(byte[] content) {
try {
if(img==null){
// TODO eventually use ByteProcessor or BinaryProcessor
// BinaryProcessor p = new ij.process.BinaryProcessor(new
// ByteProcessor(imageSizeX, imageSizeY));
img = new ImagePlus("", new ShortProcessor(imageSizeX, imageSizeY));
img.show();
}
// TODO Check whether this is needed
short[] shorts = new short[content.length / 2];
ByteBuffer.wrap(content).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
img.getProcessor().setPixels(shorts);
img.updateAndDraw();
numImageUpdates++;
} catch (Exception ex) {
logger.log(Level.SEVERE, "UpdateImage got exception", ex);
}
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
public void createAndShowGUI() {
fpsText = new JTextField(6);
fpsText.setEditable(false);
fpsText.setHorizontalAlignment(JTextField.CENTER);
frame = new JFrame("ZeroMQ_Viewer Plugin");
JPanel panel = new JPanel(new BorderLayout());
panel.setLayout(new GridBagLayout());
panel.setBorder(new EmptyBorder(new Insets(5, 5, 5, 5)));
frame.getContentPane().add(BorderLayout.CENTER, panel);
GridBagConstraints c = new GridBagConstraints();
// Add extra space around each component to avoid clutter
c.insets = new Insets(2, 2, 2, 2);
// Top row
// Anchor all components CENTER
c.anchor = GridBagConstraints.CENTER;
c.gridx = 0;
c.gridy = 0;
panel.add(new JLabel("Frames/s"), c);
// Middle row
// These widgets should be centered
c.anchor = GridBagConstraints.CENTER;
c.gridy = 1;
c.gridx = 0;
panel.add(fpsText, c);
// Display the window.
frame.pack();
frame.addWindowListener(new FrameExitListener());
frame.setVisible(true);
int timerDelay = 2000; // 2 seconds
timer = new Timer(timerDelay, new ActionListener() {
public void actionPerformed(ActionEvent event) {
long time = System.currentTimeMillis();
double fps = 1000. * numImageUpdates / (double) (time - prevTime);
fpsText.setText(String.format("%.1f", fps));
prevTime = time;
numImageUpdates = 0;
}
});
timer.start();
}
public class FrameExitListener extends WindowAdapter {
public void windowClosing(WindowEvent event) {
isPluginRunning = false;
}
}
}

View File

View File

View File