views:

363

answers:

3

Hi there, I've got an SVG image with 67 separate paths.

Are there any libraries/tutorials out there that will create a separate raster image such as a PNG for each of those paths, and perhaps name them according to the path id?

+1  A: 

I don't know of any libraries which would support this exact workflow directly, but that's probably because at least on the surface it seems super trivial. Assuming you're talking about top-level <path/> nodes, then this should be accomplishable with any library that can work with XML - just work with the raw XML directly and ignore the fact that this particular document is SVG. If you have:

<svg ...>
  <path title="a" d="M 100 100 L 300 100 L 200 300 z" stroke-width="3" />
  <path title="b" d="M 200 100 L 300 100 L 200 300 z" stroke-width="3" />
  <path title="c" d="M 300 100 L 300 100 L 200 300 z" stroke-width="3" />
</svg>

And you want:

[a.svg]
<svg ...>
  <path d="M 100 100 L 300 100 L 200 300 z" stroke="blue" stroke-width="3" />
</svg>

[b.svg]
<svg ...>
  <path d="M 200 100 L 300 100 L 200 300 z" stroke="blue" stroke-width="3" />
</svg>

Then you just need to use your language/library/tool of choice and define the path to the "path" nodes, suck them out of the root document and grab the title attribute, and copy them into a new document which shares the same original canvas attributes (if that is appropriate in your case - or change them into whatever you need) with the title as the file name. This should be pretty trivial with any XML parser and even most basic DOM handling API (or XSLT/XPATH, etc.).

Nick Bastin
My bad...I didn't explain the needed output. I need raster images for the output (e.g. PNG)...I'll revise the question.
btelles
I guess I would still do what I said, and then feed them through imagemagick or something similar to generate the raster output.
Nick Bastin
+1  A: 

The Apache Batik library is Java library for displaying and manipulating SVG content. To generate the PNG files you can use their DOM API to set the display attribute to none on all paths except the one that you want to render and then use their Transcoder API to generate the bitmaps. Loop over all path elements in the SVG document and set the display attribute to inline on one at the time to generate a bitmap for each path element.

Jonas Pegerfalk
A: 

Thanks everyone. I ended up using a combination of the two answers. I used a Ruby script to parse the SVG files and write a new one for each path, then the batik converter to generate a png from that file. The accepted answer goes to Nick because of the key insight that it's easy to create individual SVG's. Thanks Nick!

Here's the script:

require 'rubygems'
require 'nokogiri'
file = 'dark_florida_no_numbers.svg'

file_string = IO.read(file)

reader = Nokogiri::XML::Reader(file_string)

reader.each do |node|

  if node.name == 'path'
    county = node.attributes['id']
    File.open("dark/#{county}.svg", 'w') do |f|
      f.write "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.0\" >\n  <path "
      node.attributes.each do |attr, value|
        f.write " #{attr}=\"#{value}\""
      end
      f.write "/>\n</svg>"
    end
    `java -jar b/batik-rasterizer.jar dark/#{county}.svg`
  end
end
btelles