Search code examples
svgimagemagickpngminimagickmogrify

How to make SVG to PNG rendering with MiniMagick not ignore size and font options?


I'm using minimagick to do some dynamic resizing of a SVG image into a PNG one.

Here is my code:

require "mini_magick"

svgString = '<?xml version="1.0" encoding="UTF-8"?>'\
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0, 0, 512, 512">'\
  '<g id="Calque_1">'\
'    <g>'\
'      <path d="M256,432.5 C143.61,432.5 52.5,345.867 52.5,239 C52.5,132.133 143.61,45.5 256,45.5 C368.39,45.5 459.5,132.133 459.5,239 C459.5,345.867 368.39,432.5 256,432.5 z" fill="#FFFFFF"/>'\
'      <path d="M256,432.5 C143.61,432.5 52.5,345.867 52.5,239 C52.5,132.133 143.61,45.5 256,45.5 C368.39,45.5 459.5,132.133 459.5,239 C459.5,345.867 368.39,432.5 256,432.5 z" fill-opacity="0" stroke="#000000" stroke-width="1"/>'\
'    </g>'\
'    <text transform="matrix(1, 0, 0, 1, 179.125, 208)">'\
'      <tspan x="-28.125" y="10.5" font-size="24" fill="#000000">Is this using my font?</tspan>'\
'    </text>'\
'  </g>'\
'</svg>'

image = MiniMagick::Image.read(svgString)
image.combine_options do |b|
  b.resize "760x760"
  b.font "/Users/foo/Library/Fonts/myFont.ttf"
end
image.format("png", 1)
image.write('from-string.png') 

The image gets rendered, but it's a 512x512 image (the viewport size), and the font myFont is not used in the rendering.

Any idea how I could fix this?


Solution

  • I found a way to get what I wanted with mini_magick this way (only available from version 4+):

    # Write SVG in a temporary file
    temp_svg = Tempfile.new('bar')
    temp_svg.write(svg_string)
    temp_svg.close
    
    MiniMagick::Tool::Mogrify.new do |mogrify|
      mogrify.resize "760x760"
      mogrify.font "/Users/foo/Library/Fonts/myFont.ttf"
      mogrify.format "png"
      mogrify << temp_svg.path
    end
    
    temp_svg.unlink
    
    # The result is in (temp_svg.path + ".png")
    

    It's terribly ugly since I need to access the file system for both SVG and PNG. But it's the only way I could make it work.