Class: Abqari::ImagePipeline::VipsBackend

Inherits:
Object
  • Object
show all
Defined in:
lib/abqari/image_pipeline.rb

Overview

Native libvips via ruby-vips. Same operations as the shell backend but no per-image process spawn — ~5–10× faster for variant generation. Requires the vips gem AND the libvips C library; if either is missing the pipeline falls back to the shell backend automatically.

Instance Method Summary collapse

Constructor Details

#initialize(strip:) ⇒ VipsBackend

Returns a new instance of VipsBackend.



699
700
701
# File 'lib/abqari/image_pipeline.rb', line 699

def initialize(strip:)
  @strip = strip
end

Instance Method Details

#dimensions(src) ⇒ Object



734
735
736
737
738
739
# File 'lib/abqari/image_pipeline.rb', line 734

def dimensions(src)
  image = ::Vips::Image.new_from_file(src, access: :sequential)
  [image.width, image.height]
rescue ::Vips::Error
  nil
end

#nameObject



703
704
705
# File 'lib/abqari/image_pipeline.rb', line 703

def name
  'vips-native'
end

#thumbnail(src, dest, width, format, quality) ⇒ Object



707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
# File 'lib/abqari/image_pipeline.rb', line 707

def thumbnail(src, dest, width, format, quality)
  # `thumbnail` is libvips' high-level "load + resize + sharpen"
  # operation. It uses the demand-driven pipeline so memory is
  # bounded regardless of source resolution. EXIF / metadata
  # stripping is handled by the `strip:` flag on the writer —
  # no separate copy-and-clear pass needed.
  # `thumbnail` with width only preserves aspect ratio. No
  # height constraint needed; libvips computes the matching
  # height from the source.
  image = ::Vips::Image.thumbnail(src, width)

  case format
  when 'avif', 'webp'
    image.write_to_file(dest, Q: quality, strip: @strip)
  when 'original'
    ext = File.extname(dest).delete('.').downcase
    if %w[png gif].include?(ext)
      # PNG / GIF don't take a quality flag.
      image.write_to_file(dest, strip: @strip)
    else
      image.write_to_file(dest, Q: quality, strip: @strip)
    end
  else
    raise "Unknown format: #{format}"
  end
end