I use Rubyvis to generate SVG plots, and then allow the user to save either to SVG directly, or to some other format using RMagick.
The SVG plots have a set size, which is specified in the SVG file. It seems to me, then, that it should be trivial to convert to a PDF of the same size.
Unfortunately, this appears not to be the case. I can produce a PDF in this manner, but it is much larger (dimension-wise) than the PDFs produced if I first open the SVG in inkscape and then print-to-file as a PDF.
Worse, the PDF image quality is terrible.
Am I missing some instruction for Magick? Here's the code:
image = Magick::Image::from_blob(svg_string_data) { self.format = 'SVG' }
image[0].format = 'PDF'
image[0].to_blob
I then write the value returned (the PDF blob) directly into a file.
The answer comes to you based on a tip from cptjazz on github.
First of all, the documentation for RMagick is often wrong. I doubt this is a version problem, because the ImageMagick-hosted docs are v2.12.0, and I'm using v2.13.1. Either way, here is what you need to know.
The docs claim you can use image[0]['pdf', 'use-cropbox'] = true
, since true.to_s
yields the String 'true'. In fact, it needs an explicit string, and the []=
method takes only one key, not two.
I did not experiment with pdf:use-trimbox
, mainly because I wanted an option that also works for postscript. For postscript, you should be able to amend it only slightly, and set ps:use-cropbox
to 'true', but RMagick's docs are unclear as to how one may properly set the geometry on a PS, PS2, or PS3. (Normally in ImageMagick, one would set the density to '300x300' and the geometry to '24%', supposedly.) And for some reason, PS3-format output files do not scale as well as the PDFs produced by RMagick. But I digress.
Here is what I used for PDF:
image = Magick::Image::from_blob(svg_string) { self.format = 'SVG' }
image[0].format = 'PDF'
image[0]["use-cropbox"] = 'true'
image[0].to_blob
And here is what I used for PS:
image = Magick::Image::from_blob(svg_string) { self.format = 'SVG' }
page = image[0].page.dup
image[0]["use-cropbox"] = 'true'
image[0].format = 'PS3'
image[0].density = '100x100'
image[0].page = page
image[0].to_blob
For some reason, setting a higher density makes the image smaller. Why that should be is a mystery.