Class: BetterSeo::Image::Optimizer
- Inherits:
-
Object
- Object
- BetterSeo::Image::Optimizer
- Defined in:
- lib/better_seo/image/optimizer.rb
Constant Summary collapse
- SUPPORTED_FORMATS =
%w[jpg jpeg png webp gif].freeze
Instance Attribute Summary collapse
-
#quality ⇒ Object
readonly
Returns the value of attribute quality.
Instance Method Summary collapse
-
#compress(source, destination) ⇒ Object
Compress image.
-
#convert_to_webp(source, destination) ⇒ Object
Convert image to WebP.
-
#generate_responsive(source, output_dir, sizes: {}, prefix: "responsive") ⇒ Object
Generate responsive image sizes.
-
#initialize(quality: 85) ⇒ Optimizer
constructor
A new instance of Optimizer.
-
#optimize(source, destination, resize: nil) ⇒ Object
Optimize image (resize + compress).
-
#resize(source, destination, width: nil, height: nil) ⇒ Object
Resize image.
-
#validate_format!(path) ⇒ Object
Validate image format.
Constructor Details
#initialize(quality: 85) ⇒ Optimizer
Returns a new instance of Optimizer.
16 17 18 19 |
# File 'lib/better_seo/image/optimizer.rb', line 16 def initialize(quality: 85) @quality = quality check_imagemagick! end |
Instance Attribute Details
#quality ⇒ Object (readonly)
Returns the value of attribute quality.
14 15 16 |
# File 'lib/better_seo/image/optimizer.rb', line 14 def quality @quality end |
Instance Method Details
#compress(source, destination) ⇒ Object
Compress image
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/better_seo/image/optimizer.rb', line 71 def compress(source, destination) check_imagemagick! validate_source!(source) image = MiniMagick::Image.open(source) image.quality @quality image.write destination destination rescue MiniMagick::Error => e raise ImageError, "Failed to compress: #{e.}" end |
#convert_to_webp(source, destination) ⇒ Object
Convert image to WebP
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/better_seo/image/optimizer.rb', line 32 def convert_to_webp(source, destination) check_imagemagick! validate_source!(source) image = MiniMagick::Image.open(source) image.format "webp" image.quality @quality image.write destination destination rescue MiniMagick::Error => e raise ImageError, "Failed to convert to WebP: #{e.}" end |
#generate_responsive(source, output_dir, sizes: {}, prefix: "responsive") ⇒ Object
Generate responsive image sizes
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/better_seo/image/optimizer.rb', line 85 def generate_responsive(source, output_dir, sizes: {}, prefix: "responsive") check_imagemagick! validate_source!(source) FileUtils.mkdir_p(output_dir) unless File.directory?(output_dir) results = {} ext = File.extname(source) sizes.each do |name, width| output_path = File.join(output_dir, "#{prefix}_#{name}_#{width}w#{ext}") resize(source, output_path, width: width) results[name] = output_path end results rescue MiniMagick::Error => e raise ImageError, "Failed to generate responsive images: #{e.}" end |
#optimize(source, destination, resize: nil) ⇒ Object
Optimize image (resize + compress)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/better_seo/image/optimizer.rb', line 106 def optimize(source, destination, resize: nil) check_imagemagick! validate_source!(source) original_size = File.size(source) if resize resize(source, destination, **resize) else compress(source, destination) end optimized_size = File.size(destination) reduction = ((original_size - optimized_size).to_f / original_size * 100).round(2) { original_size: original_size, optimized_size: optimized_size, reduction_percent: reduction } rescue MiniMagick::Error => e raise ImageError, "Failed to optimize: #{e.}" end |
#resize(source, destination, width: nil, height: nil) ⇒ Object
Resize image
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/better_seo/image/optimizer.rb', line 47 def resize(source, destination, width: nil, height: nil) check_imagemagick! validate_source!(source) raise ImageError, "Either width or height must be specified" if width.nil? && height.nil? image = MiniMagick::Image.open(source) if width && height image.resize "#{width}x#{height}!" elsif width image.resize "#{width}x" else image.resize "x#{height}" end image.write destination destination rescue MiniMagick::Error => e raise ImageError, "Failed to resize: #{e.}" end |
#validate_format!(path) ⇒ Object
Validate image format
22 23 24 25 26 27 28 29 |
# File 'lib/better_seo/image/optimizer.rb', line 22 def validate_format!(path) ext = File.extname(path).downcase.delete(".") unless SUPPORTED_FORMATS.include?(ext) raise ImageError, "Unsupported format: #{ext}. Supported: #{SUPPORTED_FORMATS.join(", ")}" end true end |