Initial commit of the ImageJ ZeroMQ Viewer
This commit is contained in:
commit
65ab9dcca7
32
ch.psi.imagej.zeromq/.classpath
Normal file
32
ch.psi.imagej.zeromq/.classpath
Normal 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
1
ch.psi.imagej.zeromq/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
23
ch.psi.imagej.zeromq/.project
Normal file
23
ch.psi.imagej.zeromq/.project
Normal 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>
|
12
ch.psi.imagej.zeromq/.settings/org.eclipse.jdt.core.prefs
Normal file
12
ch.psi.imagej.zeromq/.settings/org.eclipse.jdt.core.prefs
Normal 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
|
@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
20
ch.psi.imagej.zeromq/pom.xml
Normal file
20
ch.psi.imagej.zeromq/pom.xml
Normal 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>
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
0
ch.psi.imagej.zeromq/src/main/resources/.gitignore
vendored
Normal file
0
ch.psi.imagej.zeromq/src/main/resources/.gitignore
vendored
Normal file
0
ch.psi.imagej.zeromq/src/test/java/.gitignore
vendored
Normal file
0
ch.psi.imagej.zeromq/src/test/java/.gitignore
vendored
Normal file
0
ch.psi.imagej.zeromq/src/test/resources/.gitignore
vendored
Normal file
0
ch.psi.imagej.zeromq/src/test/resources/.gitignore
vendored
Normal file
Loading…
x
Reference in New Issue
Block a user