ruby-thumbor 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ module Thumbor
8
8
  class Cascade
9
9
  attr_accessor :image, :old_crypto, :options, :filters
10
10
 
11
- @available_options = [:meta, :crop, :width, :height, :flip,:flop, :halign, :valign, :smart, :fit_in, :old, :trim]
11
+ @available_options = [:meta, :crop, :center, :original_width, :original_height, :width, :height, :flip,:flop, :halign, :valign, :smart, :fit_in, :old, :trim]
12
12
 
13
13
  extend Forwardable
14
14
 
@@ -53,6 +53,82 @@ module Thumbor
53
53
  end
54
54
  end
55
55
 
56
+ def calculate_centered_crop(options)
57
+ width = options[:width]
58
+ height = options[:height]
59
+ original_width = options[:original_width]
60
+ original_height = options[:original_height]
61
+ center = options[:center]
62
+
63
+ return unless original_width &&
64
+ original_height &&
65
+ center &&
66
+ (width || height)
67
+
68
+ unless center.kind_of?(Array) && center.length == 2
69
+ raise 'center must be an array of x,y'
70
+ end
71
+
72
+ center_x, center_y = center
73
+ width ||= original_width
74
+ height ||= original_height
75
+ width = width.abs
76
+ height = height.abs
77
+ new_aspect_ratio = width / height.to_f
78
+ original_aspect_ratio = original_width/original_height.to_f
79
+
80
+ crop = nil
81
+ # We're going wider, vertical crop
82
+ if new_aspect_ratio > original_aspect_ratio
83
+ # How tall should we be? because new_aspect_ratio is > original_aspect_ratio we can be sure
84
+ # that cropped_height is always less than original_height (original). This is assumed below.
85
+ cropped_height = (original_width / new_aspect_ratio).round
86
+ # Calculate coordinates around center
87
+ top_crop_point = (center_y - (cropped_height * 0.5)).round
88
+ bottom_crop_point = (center_y + (cropped_height * 0.5)).round
89
+
90
+ # If we've gone above the top of the image, take all from the bottom
91
+ if top_crop_point < 0
92
+ top_crop_point = 0
93
+ bottom_crop_point = cropped_height
94
+ # If we've gone below the top of the image, take all from the top
95
+ elsif bottom_crop_point > original_height
96
+ top_crop_point = original_height - cropped_height
97
+ bottom_crop_point = original_height
98
+ # Because cropped_height < original_height, top_crop_point and
99
+ # bottom_crop_point will never both be out of bounds
100
+ end
101
+
102
+ # Put it together
103
+ crop = [0, top_crop_point, original_width, bottom_crop_point]
104
+ # We're going taller, horizontal crop
105
+ elsif new_aspect_ratio < original_aspect_ratio
106
+ # How wide should we be? because new_aspect_ratio is < original_aspect_ratio we can be sure
107
+ # that cropped_width is always less than original_width (original). This is assumed below.
108
+ cropped_width = (original_height * new_aspect_ratio).round
109
+ # Calculate coordinates around center
110
+ left_crop_point = (center_x - (cropped_width * 0.5)).round
111
+ right_crop_point = (center_x + (cropped_width * 0.5)).round
112
+
113
+ # If we've gone beyond the left of the image, take all from the right
114
+ if left_crop_point < 0
115
+ left_crop_point = 0
116
+ right_crop_point = cropped_width
117
+ # If we've gone beyond the right of the image, take all from the left
118
+ elsif right_crop_point > original_width
119
+ left_crop_point = original_width - cropped_width
120
+ right_crop_point = original_width
121
+ # Because cropped_width < original_width, left_crop_point and
122
+ # right_crop_point will never both be out of bounds
123
+ end
124
+
125
+ # Put it together
126
+ crop = [left_crop_point, 0, right_crop_point, original_height]
127
+ end
128
+
129
+ options[:crop] = crop
130
+ end
131
+
56
132
  def url_for(options, include_hash = true)
57
133
  if not options[:image]
58
134
  raise 'image is a required argument.'
@@ -64,6 +140,8 @@ module Thumbor
64
140
  url_parts.push('meta')
65
141
  end
66
142
 
143
+ calculate_centered_crop(options)
144
+
67
145
  crop = options[:crop]
68
146
  if crop
69
147
  crop_left = crop[0]
@@ -1,3 +1,3 @@
1
1
  module Thumbor
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  end
@@ -173,6 +173,85 @@ describe Thumbor::Cascade do
173
173
  url = subject.trim('bottom-right', 15).url_for
174
174
  url.should == 'trim:bottom-right:15/' << image_md5
175
175
  end
176
+
177
+ it "should have the right crop when cropping horizontally and given a left center" do
178
+ url = subject.original_width(100).original_height(100).width(40).height(50).center(0, 50).url_for
179
+ url.should == '0x0:80x100/40x50/' << image_md5
180
+ end
181
+
182
+ it "should have the right crop when cropping horizontally and given a right center" do
183
+ url = subject.original_width(100).original_height(100).width(40).height(50).center(100, 50).url_for
184
+ url.should == '20x0:100x100/40x50/' << image_md5
185
+ end
186
+
187
+ it "should have the right crop when cropping horizontally and given the actual center" do
188
+ url = subject.original_width(100).original_height(100).width(40).height(50).center(50, 50).url_for
189
+ url.should == '10x0:90x100/40x50/' << image_md5
190
+ end
191
+
192
+ it "should have the right crop when cropping vertically and given a top center" do
193
+ url = subject.original_width(100).original_height(100).width(50).height(40).center(50, 0).url_for
194
+ url.should == '0x0:100x80/50x40/' << image_md5
195
+ end
196
+
197
+ it "should have the right crop when cropping vertically and given a bottom center" do
198
+ url = subject.original_width(100).original_height(100).width(50).height(40).center(50, 100).url_for
199
+ url.should == '0x20:100x100/50x40/' << image_md5
200
+ end
201
+
202
+ it "should have the right crop when cropping vertically and given the actual center" do
203
+ url = subject.original_width(100).original_height(100).width(50).height(40).center(50, 50).url_for
204
+ url.should == '0x10:100x90/50x40/' << image_md5
205
+ end
206
+
207
+ it "should have the no crop when not necessary" do
208
+ url = subject.original_width(100).original_height(100).width(50).height(50).center(50, 0).url_for
209
+ url.should == '50x50/' << image_md5
210
+ end
211
+
212
+ it "should blow up with a bad center" do
213
+ expect { subject.original_width(100).original_height(100).width(50).height(50).center(50).url_for }.to raise_error(RuntimeError)
214
+ end
215
+
216
+ it "should have no crop with a missing original_height" do
217
+ url = subject.original_width(100).width(50).height(40).center(50, 0).url_for
218
+ url.should == '50x40/' << image_md5
219
+ end
220
+
221
+ it "should have no crop with a missing original_width" do
222
+ url = subject.original_height(100).width(50).height(40).center(50, 0).url_for
223
+ url.should == '50x40/' << image_md5
224
+ end
225
+
226
+ it "should have no crop with out a width and height" do
227
+ url = subject.original_width(100).original_height(100).center(50, 50).url_for
228
+ url.should == image_md5
229
+ end
230
+
231
+ it "should use the original width with a missing width" do
232
+ url = subject.original_width(100).original_height(100).height(80).center(50, 50).url_for
233
+ url.should == '0x10:100x90/0x80/' << image_md5
234
+ end
235
+
236
+ it "should use the original height with a missing height" do
237
+ url = subject.original_width(100).original_height(100).width(80).center(50, 50).url_for
238
+ url.should == '10x0:90x100/80x0/' << image_md5
239
+ end
240
+
241
+ it "should have the right crop with a negative width" do
242
+ url = subject.original_width(100).original_height(100).width(-50).height(40).center(50, 50).url_for
243
+ url.should == '0x10:100x90/-50x40/' << image_md5
244
+ end
245
+
246
+ it "should have the right crop with a negative height" do
247
+ url = subject.original_width(100).original_height(100).width(50).height(-40).center(50, 50).url_for
248
+ url.should == '0x10:100x90/50x-40/' << image_md5
249
+ end
250
+
251
+ it "should have the right crop with a negative height and width" do
252
+ url = subject.original_width(100).original_height(100).width(-50).height(-40).center(50, 50).url_for
253
+ url.should == '0x10:100x90/-50x-40/' << image_md5
254
+ end
176
255
  end
177
256
 
178
257
  describe '#generate' do
@@ -141,6 +141,85 @@ describe Thumbor::CryptoURL do
141
141
  url = subject.url_for :image => image_url, :trim => ['bottom-right', 15]
142
142
  url.should == 'trim:bottom-right:15/' << image_md5
143
143
  end
144
+
145
+ it "should have the right crop when cropping horizontally and given a left center" do
146
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 40, :height => 50, :center => [0, 50]
147
+ url.should == '0x0:80x100/40x50/' << image_md5
148
+ end
149
+
150
+ it "should have the right crop when cropping horizontally and given a right center" do
151
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 40, :height => 50, :center => [100, 50]
152
+ url.should == '20x0:100x100/40x50/' << image_md5
153
+ end
154
+
155
+ it "should have the right crop when cropping horizontally and given the actual center" do
156
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 40, :height => 50, :center => [50, 50]
157
+ url.should == '10x0:90x100/40x50/' << image_md5
158
+ end
159
+
160
+ it "should have the right crop when cropping vertically and given a top center" do
161
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => 40, :center => [50, 0]
162
+ url.should == '0x0:100x80/50x40/' << image_md5
163
+ end
164
+
165
+ it "should have the right crop when cropping vertically and given a bottom center" do
166
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => 40, :center => [50, 100]
167
+ url.should == '0x20:100x100/50x40/' << image_md5
168
+ end
169
+
170
+ it "should have the right crop when cropping vertically and given the actual center" do
171
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => 40, :center => [50, 50]
172
+ url.should == '0x10:100x90/50x40/' << image_md5
173
+ end
174
+
175
+ it "should have the no crop when not necessary" do
176
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => 50, :center => [50, 0]
177
+ url.should == '50x50/' << image_md5
178
+ end
179
+
180
+ it "should blow up with a bad center" do
181
+ expect { subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => 40, :center => 50 }.to raise_error(RuntimeError)
182
+ end
183
+
184
+ it "should have no crop with a missing original_height" do
185
+ url = subject.url_for :image => image_url, :original_width => 100, :width => 50, :height => 40, :center => [50, 50]
186
+ url.should == '50x40/' << image_md5
187
+ end
188
+
189
+ it "should have no crop with a missing original_width" do
190
+ url = subject.url_for :image => image_url, :original_height => 100, :width => 50, :height => 40, :center => [50, 50]
191
+ url.should == '50x40/' << image_md5
192
+ end
193
+
194
+ it "should have no crop with out a width and height" do
195
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :center => [50, 50]
196
+ url.should == image_md5
197
+ end
198
+
199
+ it "should use the original width with a missing width" do
200
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :height => 80, :center => [50, 50]
201
+ url.should == '0x10:100x90/0x80/' << image_md5
202
+ end
203
+
204
+ it "should use the original height with a missing height" do
205
+ url = subject.url_for :image => image_url,:original_width => 100, :original_height => 100, :width => 80, :center => [50, 50]
206
+ url.should == '10x0:90x100/80x0/' << image_md5
207
+ end
208
+
209
+ it "should have the right crop with a negative width" do
210
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => -50, :height => 40, :center => [50, 50]
211
+ url.should == '0x10:100x90/-50x40/' << image_md5
212
+ end
213
+
214
+ it "should have the right crop with a negative height" do
215
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => 50, :height => -40, :center => [50, 50]
216
+ url.should == '0x10:100x90/50x-40/' << image_md5
217
+ end
218
+
219
+ it "should have the right crop with a negative height and width" do
220
+ url = subject.url_for :image => image_url, :original_width => 100, :original_height => 100, :width => -50, :height => -40, :center => [50, 50]
221
+ url.should == '0x10:100x90/-50x-40/' << image_md5
222
+ end
144
223
  end
145
224
 
146
225
  describe '#generate' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-thumbor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-25 00:00:00.000000000 Z
12
+ date: 2013-01-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec