ruby-vips
| Language | Ruby |
|---|---|
| License | MIT (libvips: LGPL-2.1; librsvg: LGPL-2.1) |
| Repository | github.com/libvips/ruby-vips |
| Documentation | rubydoc, libvips svgload |
| Depends on | libvips (8.x) built with librsvg, ffi gem |
| Read / write | read (renders SVG to raster images) / no |
ruby-vips is the Ruby binding to libvips, a fast, low-memory image processing library. libvips loads SVG with its svgload operation, which renders through librsvg, so SVG support is as complete as librsvg’s: CSS, text, filters, gradients and masks. The result is a normal raster image you can resize, composite and save as PNG, JPEG, WebP, AVIF or any other format libvips writes.
Because SVG is vector, libvips renders it at the target size instead of scaling pixels: thumbnail and the dpi/scale options give sharp output at any size. It can’t create or edit SVG.
Installation#
Install libvips with SVG support, then the gem:
# Debian / Ubuntu
sudo apt install libvips42 # or libvips-dev; built with librsvg
# macOS
brew install vips
gem install ruby-vips
Check that SVG loading is available: vips -l | grep svgload.
Basic usage: convert SVG to PNG#
require "vips"
image = Vips::Image.new_from_file("in.svg")
puts "#{image.width} x #{image.height}"
image.write_to_file("out.png")
At the default 72 DPI, one SVG pixel becomes one output pixel. The image has an alpha channel (4 bands, RGBA).
How to render SVG at a higher resolution#
Pass svgload options to new_from_file:
big = Vips::Image.new_from_file("in.svg", scale: 4) # 4x the intrinsic size
print = Vips::Image.new_from_file("in.svg", dpi: 300) # physical units at 300 DPI
big.write_to_file("out@4x.png")
How to make a thumbnail of an SVG#
thumbnail renders the SVG directly at the size you ask for (here fitting in 256 x 256):
thumb = Vips::Image.thumbnail("in.svg", 256)
thumb.write_to_file("thumb.png")
# exact box, cropped to fill it
square = Vips::Image.thumbnail("in.svg", 256, height: 256, crop: :centre)
How to convert SVG to JPEG with a white background#
JPEG has no alpha channel, so flatten first:
image = Vips::Image.new_from_file("in.svg", dpi: 144)
image.flatten(background: [255, 255, 255]).write_to_file("out.jpg", Q: 90)
How to load SVG from a string#
svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40" fill="orange"/></svg>'
image = Vips::Image.new_from_buffer(svg, "")
png_bytes = image.write_to_buffer(".png")
Tips#
- SVG files over 10 MB are rejected by default as a safety measure; pass
unlimited: trueonly for trusted files. stylesheet: "path { fill: red }"applies extra CSS when rendering (libvips 8.15+ with librsvg 2.48+).- Active Storage variants use ruby-vips, so Rails apps can create PNG previews of uploaded SVG; sanitize SVG before serving it back to browsers.