class DynamicImage::ImageSizing
DynamicImage
Image Sizing¶ ↑
Calculates cropping and fitting for image sizes.
Attributes
record[R]
Public Class Methods
new(record, options = {})
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 8 def initialize(record, options = {}) @record = record @uncropped = options[:uncropped] ? true : false end
Public Instance Methods
crop_geometry(ratio_vector)
click to toggle source
Calculates crop geometry. The given vector is scaled to match the image size, since DynamicImage
performs cropping before resizing.
Example¶ ↑
image = Image.find(params[:id]) # 320x200 image sizing = DynamicImage::ImageSizing.new(image) sizing.crop_geometry(Vector2d(100, 100)) # => [Vector2d(200, 200), Vector2d(60, 0)]
Returns a tuple with crop size and crop start vectors.
# File lib/dynamic_image/image_sizing.rb, line 26 def crop_geometry(ratio_vector) # Maximize the crop area to fit the image size crop_size = ratio_vector.fit(size).round # Ignore pixels outside the pre-cropped area for now center = crop_gravity - crop_start start = center - (crop_size / 2).floor start = clamp(start, crop_size, size) [crop_size, (start + crop_start)] end
fit(fit_size, options = {})
click to toggle source
Adjusts fit_size
to fit the image dimensions. Any dimension set to zero will be ignored.
Options¶ ↑
-
:crop
- Don’t keep aspect ratio. This will allow the image to be cropped to the requested size. -
:upscale
- Don’t limit to the size of the image. Images smaller than the given size will be scaled up.
Examples¶ ↑
image = Image.find(params[:id]) # 320x200 image sizing = DynamicImage::ImageSizing.new(image) sizing.fit(Vector2d(0, 100)) # => Vector2d(160.0, 100.0) sizing.fit(Vector2d(500, 500)) # => Vector2d(320.0, 200.0) sizing.fit(Vector2d(500, 500), crop: true) # => Vector2d(200.0, 200.0) sizing.fit(Vector2d(500, 500), upscale: true) # => Vector2d(500.0, 312.5)
# File lib/dynamic_image/image_sizing.rb, line 66 def fit(fit_size, options = {}) fit_size = parse_vector(fit_size) require_dimensions!(fit_size) if options[:crop] fit_size = size.fit(fit_size) unless options[:crop] fit_size = size.contain(fit_size) unless options[:upscale] fit_size end
Private Instance Methods
clamp(start, size, max_size)
click to toggle source
Clamps the rectangle defined by start
and size
to fit inside 0, 0 and max_size
. It is assumed that size
will always be smaller than max_size
.
Returns the start vector.
# File lib/dynamic_image/image_sizing.rb, line 105 def clamp(start, size, max_size) start += shift_vector(start) start -= shift_vector(max_size - (start + size)) start end
crop_gravity()
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 76 def crop_gravity if uncropped? && !record.crop_gravity? size / 2 else record.crop_gravity end end
crop_start()
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 84 def crop_start if uncropped? Vector2d.new(0, 0) else record.crop_start end end
parse_vector(vector)
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 111 def parse_vector(vector) vector.is_a?(String) ? str_to_vector(vector) : vector end
require_dimensions!(vector)
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 117 def require_dimensions!(vector) return if vector.x.positive? && vector.y.positive? raise DynamicImage::Errors::InvalidSizeOptions end
shift_vector(vect)
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 123 def shift_vector(vect) vector( vect.x.negative? ? vect.x.abs : 0, vect.y.negative? ? vect.y.abs : 0 ) end
size()
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 92 def size if uncropped? record.real_size else record.size end end
str_to_vector(str)
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 130 def str_to_vector(str) x, y = str.match(/(\d*)x(\d*)/)[1, 2].map(&:to_i) Vector2d.new(x, y) end
uncropped?()
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 135 def uncropped? @uncropped end
vector(width, height)
click to toggle source
# File lib/dynamic_image/image_sizing.rb, line 139 def vector(width, height) Vector2d.new(width, height) end