Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resize svg image file using librsvg Python binding

When rasterizing svg file, I would like to be able to set width and height for the resulting png file. With the following code, only the canvas is set to the desired width and height, the actual image content with the original svg file dimension is rendered in the top left corner on the (500, 600) canvas.

import cairo
import rsvg

WIDTH, HEIGHT  = 500, 600
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)

ctx = cairo.Context(surface)

svg = rsvg.Handle(file="test.svg")
svg.render_cairo(ctx)

surface.write_to_png("test.png")

What should I do to make the image content same size with cairo canvas? I tried

svg.set_property('width', 500)
svg.set_property('height', 500)

but got

TypeError: property 'width' is not writable

Also documents for librsvg python binding seem to be extremely rare, only some random code snippets on cairo site.

like image 658
btw0 Avatar asked Jul 27 '09 10:07

btw0


People also ask

How do I scale an image down in SVG?

❓ How can I resize a SVG image? First, you need to add a SVG image file: drag & drop your SVG image file or click inside the white area to choose a file. Then adjust resize settings, and click the "Resize" button. After the process completes, you can download your result file.

Does size matter in SVG?

Sizing on SVG is pretty arbitrary as it is a vector format, the layout is done with maths and so isn't dependent on the size you specify. However, if the SVG is rendered on the page and then gets resized size it can make a difference at the rendering stage.


2 Answers

There is a resize function in librsvg, but it is deprecated.

Set up a scale matrix in Cairo to change the size of your drawing:

  • setup a scale transformation matrix on your cairo context
  • draw your SVG with the .render_cairo() method
  • write your surface to PNG
like image 89
Luper Rouch Avatar answered Sep 18 '22 22:09

Luper Rouch


This is the code that works for me. It implements the answer by Luper above:

import rsvg
import cairo

# Load the svg data
svg_xml = open('topthree.svg', 'r')
svg = rsvg.Handle()
svg.write(svg_xml.read())
svg.close()

# Prepare the Cairo context
img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 
      WIDTH, 
      HEIGHT)
ctx = cairo.Context(img)

# Scale whatever is written into this context
# in this case 2x both x and y directions
ctx.scale(2, 2)
svg.render_cairo(ctx)

# Write out into a PNG file
png_io = StringIO.StringIO()
img.write_to_png(png_io)    
with open('sample.png', 'wb') as fout:
    fout.write(png_io.getvalue())
like image 28
Will Avatar answered Sep 18 '22 22:09

Will