ruby-thumbor 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/thumbor/cascade.rb +1 -1
- data/lib/thumbor/crypto_url.rb +78 -0
- data/lib/thumbor/version.rb +1 -1
- data/spec/thumbor/cascade_spec.rb +79 -0
- data/spec/thumbor/crypto_url_spec.rb +79 -0
- metadata +2 -2
data/lib/thumbor/cascade.rb
CHANGED
@@ -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
|
|
data/lib/thumbor/crypto_url.rb
CHANGED
@@ -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]
|
data/lib/thumbor/version.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|