ruby-vips
| Language | Ruby |
|---|---|
| License | MIT (libvips is LGPL-2.1) |
| Repository | github.com/libvips/ruby-vips |
| Documentation | rubydoc.info/gems/ruby-vips, libvips jp2ksave |
| Depends on | libvips 8.11+ built with OpenJPEG (loaded with FFI) |
| Read / write | yes / yes; JP2 and J2K, 8 and 16 bits per sample |
ruby-vips is the Ruby binding of libvips. It loads libvips with FFI, so the gem itself needs no compiler, but libvips must be installed. libvips reads JPEG 2000 with jp2kload and writes it with jp2ksave, both through OpenJPEG. Images are processed in a streaming pipeline, which keeps memory low even for large scans.
Every libvips operation is available as a method on Vips::Image, with options as keyword arguments.
Installation#
Shell
# Debian / Ubuntu
sudo apt install libvips42
# macOS
brew install vips
gem install ruby-vips
Check JPEG 2000 support with vips -l | grep jp2k.
Basic usage: convert JPEG 2000 to PNG and back#
Ruby
require "vips"
image = Vips::Image.new_from_file("in.jp2")
puts "#{image.width} x #{image.height}, #{image.bands} bands, #{image.format}"
image.write_to_file("out.png")
png = Vips::Image.new_from_file("out.png")
png.jp2ksave("lossless.jp2", lossless: true)
How to save lossy JPEG 2000#
Ruby
require "vips"
image = Vips::Image.new_from_file("in.tif")
image.jp2ksave("out.jp2", Q: 40, tile_width: 512, tile_height: 512)
# the same with options in the file name
image.write_to_file("out.jp2[Q=40]")
Q is a quality factor from 1 to 100 (default 48). Tiles let viewers decode regions of the file quickly.
How to load a lower resolution level#
libvips exposes JPEG 2000 resolution levels as pages: page 0 is full size, page 1 half size, and so on. The n-pages metadata item tells how many levels the file has.
Ruby
require "vips"
full = Vips::Image.new_from_file("big.jp2")
puts full.get("n-pages")
preview = Vips::Image.new_from_file("big.jp2", page: 3) # 1/8 width and height
preview.write_to_file("preview.jpg")
How to make a thumbnail#
Ruby
thumb = Vips::Image.thumbnail("big.jp2", 300) # 300 pixels wide, picks a small level first
thumb.write_to_file("thumb.webp")
Tips#
- For 16-bit JPEG 2000 (medical, satellite),
image.formatis:ushort. Convert to 8 bits for display withimage.cast(:uchar, shift: true)or scale withimage.scaleimage. - Pass
fail_on: :errortonew_from_fileto stop on damaged files instead of returning a partly decoded image.