diff --git a/pom.xml b/pom.xml
index e849d0e..2835f4e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
imagej.public
http://maven.imagej.net/content/groups/public
-
+
@@ -48,6 +48,7 @@
SVG_ROI
+ C:/Fiji
@@ -55,6 +56,11 @@
net.imagej
ij
+
+ sc.fiji
+ fiji-lib
+ 2.1.1
+
batik
batik-all
diff --git a/src/main/java/SVG_ROI.java b/src/main/java/SVG_ROI.java
index d6aabac..d91d16a 100644
--- a/src/main/java/SVG_ROI.java
+++ b/src/main/java/SVG_ROI.java
@@ -1,133 +1,236 @@
-import org.apache.batik.*;
-import org.apache.batik.bridge.BridgeContext;
-import org.apache.batik.bridge.DocumentLoader;
-import org.apache.batik.bridge.GVTBuilder;
-import org.apache.batik.bridge.UserAgent;
-import org.apache.batik.bridge.UserAgentAdapter;
+import java.awt.Color;
+import java.awt.geom.PathIterator;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
-import org.apache.batik.dom.svg.SVGOMSVGElement;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
-import ij.IJ;
-
-import java.net.URI;
-import java.io.Console;
-import java.io.File;
-import java.io.IOException;
+import fiji.util.gui.GenericDialogPlus;
+import ij.ImageJ;
+import ij.gui.Roi;
+import ij.gui.ShapeRoi;
+import ij.plugin.PlugIn;
+import ij.plugin.frame.RoiManager;
/**
* Responsible for converting all SVG path elements into MetaPost curves.
*/
-public class SVG_ROI {
- private static final String PATH_ELEMENT_NAME = "path";
-
- private Document svgDocument;
-
- /**
- * Creates an SVG Document given a URI.
- *
- * @param uri Path to the file.
- * @throws Exception Something went wrong parsing the SVG file.
- */
- public SVG_ROI( String uri ) throws IOException {
- setSVGDocument( createSVGROIs( uri ) );
- }
-
- /**
- * Finds all the path nodes and converts them to MetaPost code.
- */
- public void run() {
- NodeList pathNodes = getPathElements();
- int pathNodeCount = pathNodes.getLength();
-
- for( int iPathNode = 0; iPathNode < pathNodeCount; iPathNode++ ) {
- System.out.println(pathNodes.item(iPathNode).toString());
- }
- }
-
- /**
- * Returns a list of elements in the SVG document with names that
- * match PATH_ELEMENT_NAME.
- *
- * @return The list of "path" elements in the SVG document.
- */
- private NodeList getPathElements() {
- return getSVGDocumentRoot().getElementsByTagName( PATH_ELEMENT_NAME );
- }
-
- /**
- * Returns an SVGOMSVGElement that is the document's root element.
- *
- * @return The SVG document typecast into an SVGOMSVGElement.
- */
- private Element getSVGDocumentRoot() {
- return getSVGDocument().getDocumentElement();
- }
-
- /**
- * This will set the document to parse. This method also initializes
- * the SVG DOM enhancements, which are necessary to perform SVG and CSS
- * manipulations. The initialization is also required to extract information
- * from the SVG path elements.
- *
- * @param document The document that contains SVG content.
- */
- public void setSVGDocument( Document document ) {
- initSVGDOM( document );
- this.svgDocument = document;
- }
-
- /**
- * Returns the SVG document parsed upon instantiating this class.
- *
- * @return A valid, parsed, non-null SVG document instance.
- */
- public Document getSVGDocument() {
- return this.svgDocument;
- }
-
- /**
- * Enhance the SVG DOM for the given document to provide CSS- and SVG-specific
- * DOM interfaces.
- *
- * @param document The document to enhance.
- * @link http://wiki.apache.org/xmlgraphics-batik/BootSvgAndCssDom
- */
- private void initSVGDOM( Document document ) {
- UserAgent userAgent = new UserAgentAdapter();
- DocumentLoader loader = new DocumentLoader( userAgent );
- BridgeContext bridgeContext = new BridgeContext( userAgent, loader );
- bridgeContext.setDynamicState( BridgeContext.DYNAMIC );
-
- // Enable CSS- and SVG-specific enhancements.
- (new GVTBuilder()).build( bridgeContext, document );
- }
-
- /**
- * Use the SAXSVGDocumentFactory to parse the given URI into a DOM.
- *
- * @param uri The path to the SVG file to read.
- * @return A Document instance that represents the SVG file.
- * @throws Exception The file could not be read.
- */
- private Document createSVGROIs( String uri ) throws IOException {
- String parser = XMLResourceDescriptor.getXMLParserClassName();
- SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory( parser );
- return factory.createDocument( uri );
- }
-
- /**
- * Reads a file and parses the path elements.
- *
- * @param args args[0] - Filename to parse.
- * @throws IOException Error reading the SVG file.
- */
- public static void main( String args[] ) throws IOException {
- URI uri = new File( "D:\\People\\Bianca\\svg\\Annotation2014_141_0000.svg" ).toURI();
- SVG_ROI svgroi = new SVG_ROI( uri.toString() );
- svgroi.run();
- }
+public class SVG_ROI implements PlugIn{
+ private static final String PATH_ELEMENT_NAME = "path";
+
+ @Override
+ public void run(String arg0) {
+ RoiManager rm = RoiManager.getInstance();
+ if (rm == null) {
+ rm = new RoiManager();
+ }
+
+ GenericDialogPlus gd = new GenericDialogPlus("SVGs To ROI Conversion");
+ gd.addDirectoryField("SVG Folder", "");
+
+ gd.showDialog();
+
+ if (gd.wasCanceled())
+ return;
+
+ //Navigate folder
+ File folder = new File(gd.getNextString());
+
+ File[] filelist = folder.listFiles(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".svg");
+ }
+ });
+
+ File save_folder = new File(folder.getAbsolutePath()+File.separator+"ROI Sets");
+ save_folder.mkdirs();
+ for (File file : filelist) {
+ rm.reset();
+ convertSVGToRois(file);
+ // Save the ROIs to a subfolder
+ rm.runCommand("Save", save_folder.getAbsolutePath()+File.separator+file.getName().substring(0, file.getName().length()-4)+".zip");
+
+ }
+
+ }
+ public static void convertSVGToRois(File file) {
+ RoiManager rm = RoiManager.getInstance2();
+ if (rm == null) {
+ rm = new RoiManager();
+ }
+
+ URI uri = file.toURI();
+ Document svg = null;
+ //Prepare SVG file
+ try {
+ svg = createDocument( uri.toString() );
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ // Iterate through the paths
+ NodeList pathNodes = svg.getDocumentElement().getElementsByTagName( PATH_ELEMENT_NAME );
+ int pathNodeCount = pathNodes.getLength();
+ for( int iPathNode = 0; iPathNode < pathNodeCount; iPathNode++ ) {
+ rm.addRoi(convertToShapeRoi(pathNodes.item(iPathNode).getAttributes()));
+ }
+ }
+
+ public static ArrayList convertSVGFileToRois(File file) {
+ RoiManager rm = RoiManager.getInstance2();
+ if (rm == null) {
+ rm = new RoiManager();
+ }
+
+ URI uri = file.toURI();
+ Document svg = null;
+ //Prepare SVG file
+ try {
+ svg = createDocument( uri.toString() );
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ ArrayList rois = new ArrayList();
+
+ // Iterate through the paths
+ NodeList pathNodes = svg.getDocumentElement().getElementsByTagName( PATH_ELEMENT_NAME );
+ int pathNodeCount = pathNodes.getLength();
+ for( int iPathNode = 0; iPathNode < pathNodeCount; iPathNode++ ) {
+ rois.add(convertToShapeRoi(pathNodes.item(iPathNode).getAttributes()));
+ }
+ return rois;
+ }
+
+
+ private static Roi convertToShapeRoi(NamedNodeMap pathAttributes) {
+ //Get the paths
+ String paths = pathAttributes.getNamedItem("d").getTextContent();
+
+ // Remove the Z key if there
+ int is_closed = 0;
+ if (paths.endsWith("Z")) {
+ paths = paths.substring(0, paths.length()-1);
+ is_closed = 1;
+ }
+
+ // Get the fill or Stroke, at least
+ String stroke = pathAttributes.getNamedItem("stroke").getTextContent();
+
+ // Work on a shapeRoi, as this allows for multiple ROIs to make a shape...
+ // ShapeRois can be built similarily to paths in SVG
+
+ paths = paths.trim();
+ String[] commands = paths.split("(?=L)|(?=M)|(?=C)");
+
+ ArrayList instructions = new ArrayList();
+
+ for (String command : commands ) {
+ char c = command.charAt(0);
+ command = command.trim();
+
+ command = command.substring(1);
+
+ switch (c) {
+ case 'M': // This also means that we need to start a new path...
+ instructions.add((float)PathIterator.SEG_MOVETO);
+ // Add the two coordinates
+ instructions.addAll(parseCoordinateAsArray(command," "));
+
+ break;
+
+ case 'L':
+ instructions.add((float)PathIterator.SEG_LINETO);
+ instructions.addAll(parseCoordinateAsArray(command,","));
+ break;
+ case 'C':
+
+ instructions.addAll(parseCurveAsArray(command));
+ break;
+
+ default:
+ System.out.println("WHAT IS: "+c +": "+command+"?");
+ break;
+ }
+ }
+
+ float[] floatArray = new float[instructions.size()+is_closed];
+ int i = 0;
+
+ for (Float f : instructions) {
+ floatArray[i++] = (f != null ? f : Float.NaN); // Or whatever default you want.
+ }
+ if( is_closed == 1)
+ floatArray[i] = PathIterator.SEG_CLOSE;
+
+ ShapeRoi the_roi = new ShapeRoi(floatArray);
+ the_roi.setStrokeColor(Color.decode(stroke));
+ return the_roi;
+ }
+
+ private static ArrayList parseCurveAsArray(String command) {
+ // Split at spaces first
+ ArrayList curve_points = new ArrayList();
+
+ String[] curve = command.split(" ");
+ // should be multiples of 3
+ if (curve.length%3 == 0) {
+
+ for (int i=0; i parseCoordinateAsArray(String cs, String delimiter) {
+ String[] xy = cs.split(delimiter);
+ ArrayList aPoint = new ArrayList();
+ aPoint.add(Float.parseFloat(xy[0]));
+ aPoint.add(Float.parseFloat(xy[1]));
+ return aPoint;
+ }
+
+ /**
+ * Use the SAXSVGDocumentFactory to parse the given URI into a DOM.
+ *
+ * @param uri The path to the SVG file to read.
+ * @return A Document instance that represents the SVG file.
+ * @throws Exception The file could not be read.
+ */
+ private static Document createDocument( String uri ) throws IOException {
+ String parser = XMLResourceDescriptor.getXMLParserClassName();
+ SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory( parser );
+ return factory.createDocument( uri );
+ }
+
+/**
+ * Main method for debugging.
+ * @param args unused
+ */
+public static void main(String[] args) {
+ // set the plugins.dir property to make the plugin appear in the Plugins menu
+ Class> clazz = SVG_ROI.class;
+ String url = clazz.getResource("/" + clazz.getName().replace('.', '/') + ".class").toString();
+ String pluginsDir = url.substring(5, url.length() - clazz.getName().length() - 6);
+ System.setProperty("plugins.dir", pluginsDir);
+
+ // start ImageJ
+ new ImageJ();
+}
}
\ No newline at end of file
diff --git a/src/main/resources/plugins.config b/src/main/resources/plugins.config
index 3435b67..a61fafe 100644
--- a/src/main/resources/plugins.config
+++ b/src/main/resources/plugins.config
@@ -9,4 +9,4 @@
# If something like ("") is appended to the class name, the setup() method
# will get that as arg parameter; otherwise arg is simply the empty string.
-Plugins>BIOP, "DEMO Plugin", Demo_Plugin
+Plugins>BIOP, "SVG to ROI", SVG_ROI