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.
- 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
|