class ImageProcessing::Vips::Processor

Constants

SHARPEN_MASK

Default sharpening mask that provides a fast and mild sharpen.

Public Class Methods

load_image(path_or_image, loader: nil, autorot: true, **options) click to toggle source

Loads the image on disk into a Vips::Image object. Accepts additional loader-specific options (e.g. interlacing). Afterwards auto-rotates the image to be upright.

# File lib/image_processing/vips.rb, line 30
def self.load_image(path_or_image, loader: nil, autorot: true, **options)
  if path_or_image.is_a?(::Vips::Image)
    image = path_or_image
  else
    path = path_or_image

    if loader
      image = ::Vips::Image.public_send(:"#{loader}load", path, **options)
    else
      options = Utils.select_valid_loader_options(path, options)
      image = ::Vips::Image.new_from_file(path, **options)
    end
  end

  image = image.autorot if autorot && !options.key?(:autorotate)
  image
end
save_image(image, path, saver: nil, quality: nil, **options) click to toggle source

Writes the Vips::Image object to disk. This starts the processing pipeline defined in the Vips::Image object. Accepts additional saver-specific options (e.g. quality).

# File lib/image_processing/vips.rb, line 56
def self.save_image(image, path, saver: nil, quality: nil, **options)
  options[:Q] = quality if quality

  if saver
    image.public_send(:"#{saver}save", path, **options)
  else
    options = Utils.select_valid_saver_options(path, options)
    image.write_to_file(path, **options)
  end
end
supports_resize_on_load?() click to toggle source

See thumbnail.

# File lib/image_processing/vips.rb, line 49
def self.supports_resize_on_load?
  true
end

Public Instance Methods

composite(overlay, _mode = nil, mode: "over", gravity: "north-west", offset: nil, **options) click to toggle source

Overlays the specified image over the current one. Supports specifying composite mode, direction or offset of the overlay image.

# File lib/image_processing/vips.rb, line 100
def composite(overlay, _mode = nil, mode: "over", gravity: "north-west", offset: nil, **options)
  # if the mode argument is given, call the original Vips::Image#composite
  if _mode
    overlay = [overlay] unless overlay.is_a?(Array)
    overlay = overlay.map { |object| convert_to_image(object, "overlay") }

    return image.composite(overlay, _mode, **options)
  end

  overlay = convert_to_image(overlay, "overlay")
  # add alpha channel so that #gravity can use a transparent background
  overlay = overlay.add_alpha unless overlay.has_alpha?

  # apply offset with correct gravity and make remainder transparent
  if offset
    opposite_gravity = gravity.to_s.gsub(/\w+/, "north"=>"south", "south"=>"north", "east"=>"west", "west"=>"east")
    overlay = overlay.gravity(opposite_gravity, overlay.width + offset.first, overlay.height + offset.last)
  end

  # create image-sized transparent background and apply specified gravity
  overlay = overlay.gravity(gravity, image.width, image.height)

  # apply the composition
  image.composite(overlay, mode, **options)
end
remove(*args) click to toggle source
# File lib/image_processing/vips.rb, line 130
def remove(*args)    image.tap { |img| img.remove(*args) }    end
resize_and_pad(width, height, gravity: "centre", extend: nil, background: nil, alpha: nil, **options) click to toggle source

Resizes the image to fit within the specified dimensions and fills the remaining area with the specified background color.

# File lib/image_processing/vips.rb, line 87
def resize_and_pad(width, height, gravity: "centre", extend: nil, background: nil, alpha: nil, **options)
  image = thumbnail(width, height, **options)
  image = image.add_alpha if alpha && !image.has_alpha?
  image.gravity(gravity, width, height, extend: extend, background: background)
end
resize_to_fill(width, height, **options) click to toggle source

Resizes the image to fill the specified dimensions, applying any necessary cropping.

# File lib/image_processing/vips.rb, line 81
def resize_to_fill(width, height, **options)
  thumbnail(width, height, crop: :centre, **options)
end
resize_to_fit(width, height, **options) click to toggle source

Resizes the image to fit within the specified dimensions.

# File lib/image_processing/vips.rb, line 74
def resize_to_fit(width, height, **options)
  width, height = default_dimensions(width, height)
  thumbnail(width, height, **options)
end
resize_to_limit(width, height, **options) click to toggle source

Resizes the image to not be larger than the specified dimensions.

# File lib/image_processing/vips.rb, line 68
def resize_to_limit(width, height, **options)
  width, height = default_dimensions(width, height)
  thumbnail(width, height, size: :down, **options)
end
rotate(degrees, **options) click to toggle source

Rotates the image by an arbitrary angle.

# File lib/image_processing/vips.rb, line 94
def rotate(degrees, **options)
  image.similarity(angle: degrees, **options)
end
set(*args) click to toggle source

make metadata setter methods chainable

# File lib/image_processing/vips.rb, line 127
def set(*args)       image.tap { |img| img.set(*args) }       end
set_type(*args) click to toggle source
# File lib/image_processing/vips.rb, line 128
def set_type(*args)  image.tap { |img| img.set_type(*args) }  end
set_value(*args) click to toggle source
# File lib/image_processing/vips.rb, line 129
def set_value(*args) image.tap { |img| img.set_value(*args) } end

Private Instance Methods

convert_to_image(object, name) click to toggle source

Converts the image on disk in various forms into a Vips::Image object.

# File lib/image_processing/vips.rb, line 160
def convert_to_image(object, name)
  return object if object.is_a?(::Vips::Image)

  if object.is_a?(String)
    path = object
  elsif object.respond_to?(:to_path)
    path = object.to_path
  elsif object.respond_to?(:path)
    path = object.path
  else
    raise ArgumentError, "#{name} must be a Vips::Image, String, Pathname, or respond to #path"
  end

  ::Vips::Image.new_from_file(path)
end
default_dimensions(width, height) click to toggle source

Hack to allow omitting one dimension.

# File lib/image_processing/vips.rb, line 153
def default_dimensions(width, height)
  raise Error, "either width or height must be specified" unless width || height

  [width || ::Vips::MAX_COORD, height || ::Vips::MAX_COORD]
end
thumbnail(width, height, sharpen: SHARPEN_MASK, **options) click to toggle source

Resizes the image according to the specified parameters, and sharpens the resulting thumbnail.

# File lib/image_processing/vips.rb, line 136
def thumbnail(width, height, sharpen: SHARPEN_MASK, **options)
  if self.image.is_a?(String) # path
    # resize on load
    image = ::Vips::Image.thumbnail(self.image, width, height: height, **options)
  else
    # we're already calling Image#autorot when loading the image
    no_rotate = ::Vips.at_least_libvips?(8, 8) ? { no_rotate: true } : { auto_rotate: false }
    options   = no_rotate.merge(options)

    image = self.image.thumbnail_image(width, height: height, **options)
  end

  image = image.conv(sharpen, precision: :integer) if sharpen
  image
end