class Thumbor::CryptoURL
Public Class Methods
new(key = nil)
click to toggle source
# File lib/thumbor/crypto_url.rb 10 def initialize(key = nil) 11 @key = key 12 end
Public Instance Methods
calculate_centered_crop(options)
click to toggle source
# File lib/thumbor/crypto_url.rb 40 def calculate_centered_crop(options) 41 width = options[:width] 42 height = options[:height] 43 original_width = options[:original_width] 44 original_height = options[:original_height] 45 center = options[:center] 46 47 return unless original_width && 48 original_height && 49 center && 50 (width || height) 51 52 raise 'center must be an array of x,y' unless center.is_a?(Array) && center.length == 2 53 54 center_x, center_y = center 55 width ||= original_width 56 height ||= original_height 57 width = width.abs 58 height = height.abs 59 new_aspect_ratio = width / height.to_f 60 original_aspect_ratio = original_width / original_height.to_f 61 62 crop = nil 63 # We're going wider, vertical crop 64 if new_aspect_ratio > original_aspect_ratio 65 # How tall should we be? because new_aspect_ratio is > original_aspect_ratio we can be sure 66 # that cropped_height is always less than original_height (original). This is assumed below. 67 cropped_height = (original_width / new_aspect_ratio).round 68 # Calculate coordinates around center 69 top_crop_point = (center_y - (cropped_height * 0.5)).round 70 bottom_crop_point = (center_y + (cropped_height * 0.5)).round 71 72 # If we've gone above the top of the image, take all from the bottom 73 if top_crop_point.negative? 74 top_crop_point = 0 75 bottom_crop_point = cropped_height 76 # If we've gone below the top of the image, take all from the top 77 elsif bottom_crop_point > original_height 78 top_crop_point = original_height - cropped_height 79 bottom_crop_point = original_height 80 # Because cropped_height < original_height, top_crop_point and 81 # bottom_crop_point will never both be out of bounds 82 end 83 84 # Put it together 85 crop = [0, top_crop_point, original_width, bottom_crop_point] 86 # We're going taller, horizontal crop 87 elsif new_aspect_ratio < original_aspect_ratio 88 # How wide should we be? because new_aspect_ratio is < original_aspect_ratio we can be sure 89 # that cropped_width is always less than original_width (original). This is assumed below. 90 cropped_width = (original_height * new_aspect_ratio).round 91 # Calculate coordinates around center 92 left_crop_point = (center_x - (cropped_width * 0.5)).round 93 right_crop_point = (center_x + (cropped_width * 0.5)).round 94 95 # If we've gone beyond the left of the image, take all from the right 96 if left_crop_point.negative? 97 left_crop_point = 0 98 right_crop_point = cropped_width 99 # If we've gone beyond the right of the image, take all from the left 100 elsif right_crop_point > original_width 101 left_crop_point = original_width - cropped_width 102 right_crop_point = original_width 103 # Because cropped_width < original_width, left_crop_point and 104 # right_crop_point will never both be out of bounds 105 end 106 107 # Put it together 108 crop = [left_crop_point, 0, right_crop_point, original_height] 109 end 110 111 options[:crop] = crop 112 end
calculate_width_and_height(url_parts, options)
click to toggle source
# File lib/thumbor/crypto_url.rb 14 def calculate_width_and_height(url_parts, options) 15 width = options[:width] 16 height = options[:height] 17 18 width *= -1 if width && options[:flip] 19 height *= -1 if height && options[:flop] 20 21 if width || height 22 width ||= 0 23 height ||= 0 24 end 25 26 has_width = width 27 has_height = height 28 if options[:flip] && !has_width && !has_height 29 width = '-0' 30 height = '0' if !has_height && !(options[:flop]) 31 end 32 if options[:flop] && !has_width && !has_height 33 height = '-0' 34 width = '0' if !has_width && !(options[:flip]) 35 end 36 37 url_parts.push("#{width}x#{height}") if width || height 38 end
generate(options)
click to toggle source
# File lib/thumbor/crypto_url.rb 175 def generate(options) 176 thumbor_path = [] 177 178 image_options = url_for(options) 179 thumbor_path << "#{image_options}/" unless image_options.empty? 180 181 thumbor_path << options[:image] 182 183 if @key.nil? 184 thumbor_path.insert(0, '/unsafe/') 185 else 186 signature = url_safe_base64(OpenSSL::HMAC.digest('sha1', @key, thumbor_path.join)) 187 thumbor_path.insert(0, "/#{signature}/") 188 end 189 thumbor_path.join 190 end
url_for(options)
click to toggle source
# File lib/thumbor/crypto_url.rb 114 def url_for(options) 115 raise 'image is a required argument.' unless options[:image] 116 117 url_parts = [] 118 119 url_parts.push('debug') if options[:debug] 120 121 if options[:trim] 122 trim_options = ['trim'] 123 trim_options << options[:trim] unless (options[:trim] == true) || (options[:trim][0] == true) 124 url_parts.push(trim_options.join(':')) 125 end 126 127 url_parts.push('meta') if options[:meta] 128 129 calculate_centered_crop(options) 130 131 crop = options[:crop] 132 if crop 133 crop_left = crop[0] 134 crop_top = crop[1] 135 crop_right = crop[2] 136 crop_bottom = crop[3] 137 138 if crop_left.positive? || crop_top.positive? || crop_bottom.positive? || crop_right.positive? 139 url_parts.push(crop_left.to_s << 'x' << crop_top.to_s << ':' << crop_right.to_s << 'x' << crop_bottom.to_s) 140 end 141 end 142 143 %i[fit_in adaptive_fit_in full_fit_in adaptive_full_fit_in].each do |fit| 144 url_parts.push(fit.to_s.gsub('_', '-')) if options[fit] 145 end 146 147 if (options.include?(:fit_in) || options.include?(:full_fit_in)) && !(options.include?(:width) || options.include?(:height)) 148 raise ArgumentError, 'When using fit-in or full-fit-in, you must specify width and/or height.' 149 end 150 151 calculate_width_and_height(url_parts, options) 152 153 url_parts.push(options[:halign]) if options[:halign] && (options[:halign] != :center) 154 155 url_parts.push(options[:valign]) if options[:valign] && (options[:valign] != :middle) 156 157 url_parts.push('smart') if options[:smart] 158 159 if options[:filters] && !options[:filters].empty? 160 filter_parts = [] 161 options[:filters].each do |filter| 162 filter_parts.push(filter) 163 end 164 165 url_parts.push("filters:#{filter_parts.join(':')}") 166 end 167 168 url_parts.join('/') 169 end
url_safe_base64(str)
click to toggle source
# File lib/thumbor/crypto_url.rb 171 def url_safe_base64(str) 172 Base64.encode64(str).gsub('+', '-').gsub('/', '_').gsub!(/\n/, '') 173 end