ruby-vips
| Language | Ruby |
|---|---|
| License | MIT (libvips: LGPL-2.1) |
| Repository | github.com/libvips/ruby-vips |
| Documentation | ruby-vips API docs |
| Depends on | libvips built with libheif and an AV1 codec (system library, loaded with FFI) |
| Read / write | yes / yes, 8/10/12-bit, alpha, animated AVIF |
ruby-vips is the Ruby binding of libvips. It loads the system libvips through FFI, so AVIF support depends on how your libvips was built: it needs libheif with an AV1 decoder (dav1d or libaom) to read and an AV1 encoder (libaom, SVT-AV1 or rav1e) to write. Writing to a .avif file selects AV1 compression in heifsave.
Installation#
Shell
# libvips with AVIF support
sudo apt install libvips42 libheif-plugin-dav1d libheif-plugin-aomenc # Debian / Ubuntu
brew install vips # macOS
gem install ruby-vips
Check that AVIF works: vips -l | grep -i heif lists heifload and heifsave, and vips copy in.jpg out.avif should succeed.
Basic usage: convert to AVIF and back#
Ruby
require "vips"
image = Vips::Image.new_from_file("photo.jpg", access: :sequential)
puts "#{image.width} x #{image.height}, #{image.bands} bands"
image.write_to_file("photo.avif", Q: 60) # the .avif suffix selects AV1
avif = Vips::Image.new_from_file("photo.avif")
avif.write_to_file("photo.png")
How to make an AVIF thumbnail#
Ruby
require "vips"
thumb = Vips::Image.thumbnail("photo.jpg", 400) # 400 pixels wide
thumb.write_to_file("thumb.avif", Q: 55, effort: 4)
How to set effort, bit depth and lossless mode#
Ruby
image = Vips::Image.new_from_file("photo.png")
image.heifsave("out.avif",
compression: :av1,
Q: 60,
effort: 2, # 0 (fastest) .. 9 (slowest, smallest)
bitdepth: 10, # 8, 10 or 12
subsample_mode: :off) # keep 4:4:4 chroma
image.heifsave("lossless.avif", compression: :av1, lossless: true)
How to encode AVIF to a string#
Ruby
data = image.heifsave_buffer(compression: :av1, Q: 60)
# or: image.write_to_buffer(".avif", Q: 60)
How to create AVIF variants in Rails#
With Active Storage and the image_processing gem using vips:
Ruby
# config/application.rb
config.active_storage.variant_processor = :vips
# in a view or controller
variant = user.avatar.variant(resize_to_limit: [400, 400], format: :avif, saver: { quality: 60 })
Tips#
Vips::Image.new_from_filereads only the header:width,heightandhas_alpha?don’t decode pixels.- Load all frames of an animated AVIF with
Vips::Image.new_from_file("anim.avif", n: -1); frames are stacked vertically, eachget("page-height")pixels tall.