-2

I'm reading text files in java where I use the scanner class to read text in SVG format. I have seen answers that recommend Batik. I would like to know how to use Batik only on the path data in SVG format. I want to evaluate the path and extract points that would trace out the path. Can I do this using Batik without having to evaluate the entire file in Batik?

I was trying to create my own path parser but I don't have enough time or skill to do so. I am evaluating tags in SVG format by splitting them using < and /> and I am stuck on evaluating the d attribute of paths. Here's an example of a path that I need to evaluate:

<html>
<body>

<svg width="10000" height="1000">
<path id="square" fill="#0000FF" 
d="M351.3,251 l-3.1-2.2c-0.3-0.2-0.3-0.5-0.1-0.8l2.2-3.1c0.2-0.3,0.5-0.3,0.8-0.1l3.1,2.2
c0.3,0.2,0.3,0.5,0.1,0.8l-2.2,3.1C355,251.1,354.6,251.2,354.3,251z"/>

</body>
</html>

I need the points along this path.

the_ritz
  • 322
  • 2
  • 17

2 Answers2

3

The path parsing with Batik looks fairly simple:

It appears like you just have to create a class that implements the PathHandler interface.

class MyPathHandler implements PathHandler
{
  void  startPath() { ... }
  void  movetoAbs(float x, float y)
  ... etc...
  void  endPath() { ... }
}

Then do:

  PathParser parser = new PathParser();
  parser.setPathHandler(new MyPathHandler());
  parser.parse("M351.3,251 l-3.1-2.2 ... snip ... C355,251.1,354.6,251.2,354.3,251z");
  parser.doParse();

The moveToAbs() method will be called whenever the PathParser encounters an M command etc.

If that doesn't work then I was able to find at least four or five instances of SVG path parsing code in Java or JS in about one minute of googling.

As for the sampling part. That's a lot trickier. You'll need code to measure the length of quadratic and cubic beziers, and arcs. The latter will probably involve converting the arcs (A/a) to centre parameterization (theres information in the spec on how to do that). It's not trivial to do all this. There'll be code for it, if you can find it, in Batik, Firefox, Chrome, Android etc. Perhaps there is also code out there that someone has already built.

It would be easy if you were doing it in a browser. There have already been questions asked and answered here on that.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Thanks, this was the help I needed. I was using the wrong keywords in Google due to my inexperience. I should have searched "svg path data parsing in java" rather than "svg paths in java". – the_ritz Aug 07 '19 at 07:05
  • While there have been questions asked about this exact issue, there continues to be no clear answer. The method that was shown in python is exactly what I need, except I need it in Java. I do not know how to send information between java and python. If I knew these things, I wouldn't be here. I'm not dealing with irregular shapes, it's mostly rounded squares and circles. I was searching for something that would give me points on the path, but it seems that nobody knows that kind of tool. – the_ritz Aug 07 '19 at 09:27
  • It's also possible in JS, by moving an object along the path. The only problem is that I haven't found an equivalent method in Java – the_ritz Aug 07 '19 at 09:46
0

Building upon Paul LeBeau's answer, Batik evolved a bit, here is an updated version for Batik 1.16:

class MyPathHandler extends DefaultPathHandler {
    public void startPath() { ... }

    public void movetoAbs(float x, float y) throws ParseException {
        System.out.println("Move abs to " + x + ", " + y);
    }
    
    public void movetoRel(float x, float y) throws ParseException {
        System.out.println("Move rel to " + x + ", " + y);
    }

    public void endPath() { ... }
}

and

PathParser parser = new PathParser();
parser.setPathHandler(new MyPathHandler());
parser.parse("M351.3,251 l-3.1-2.2 ... snip ... C355,251.1,354.6,251.2,354.3,251z");
DaHoC
  • 314
  • 1
  • 4
  • 14