carrierwave 1.3.4 → 3.1.2
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.
- checksums.yaml +4 -4
- data/README.md +278 -86
- data/lib/carrierwave/compatibility/paperclip.rb +4 -2
- data/lib/carrierwave/downloader/base.rb +101 -0
- data/lib/carrierwave/downloader/remote_file.rb +68 -0
- data/lib/carrierwave/locale/en.yml +9 -6
- data/lib/carrierwave/mount.rb +53 -61
- data/lib/carrierwave/mounter.rb +169 -77
- data/lib/carrierwave/orm/activerecord.rb +23 -58
- data/lib/carrierwave/processing/mini_magick.rb +137 -123
- data/lib/carrierwave/processing/rmagick.rb +47 -20
- data/lib/carrierwave/processing/vips.rb +315 -0
- data/lib/carrierwave/processing.rb +1 -0
- data/lib/carrierwave/sanitized_file.rb +83 -70
- data/lib/carrierwave/storage/abstract.rb +5 -5
- data/lib/carrierwave/storage/file.rb +6 -5
- data/lib/carrierwave/storage/fog.rb +114 -62
- data/lib/carrierwave/storage.rb +1 -0
- data/lib/carrierwave/test/matchers.rb +11 -7
- data/lib/carrierwave/uploader/cache.rb +40 -24
- data/lib/carrierwave/uploader/callbacks.rb +1 -1
- data/lib/carrierwave/uploader/configuration.rb +42 -19
- data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
- data/lib/carrierwave/uploader/content_type_denylist.rb +62 -0
- data/lib/carrierwave/uploader/dimension.rb +66 -0
- data/lib/carrierwave/uploader/download.rb +2 -123
- data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
- data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
- data/lib/carrierwave/uploader/file_size.rb +2 -2
- data/lib/carrierwave/uploader/mountable.rb +6 -0
- data/lib/carrierwave/uploader/processing.rb +45 -7
- data/lib/carrierwave/uploader/proxy.rb +17 -4
- data/lib/carrierwave/uploader/serialization.rb +1 -1
- data/lib/carrierwave/uploader/store.rb +73 -7
- data/lib/carrierwave/uploader/url.rb +7 -4
- data/lib/carrierwave/uploader/versions.rb +161 -111
- data/lib/carrierwave/uploader.rb +10 -17
- data/lib/carrierwave/utilities/file_name.rb +47 -0
- data/lib/carrierwave/utilities/uri.rb +14 -11
- data/lib/carrierwave/utilities.rb +1 -0
- data/lib/carrierwave/validations/active_model.rb +7 -9
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +22 -17
- data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +5 -4
- data/lib/generators/uploader_generator.rb +3 -3
- metadata +94 -47
- data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
- data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
- data/lib/carrierwave/uploader/extension_blacklist.rb +0 -51
- data/lib/carrierwave/uploader/extension_whitelist.rb +0 -52
|
@@ -21,9 +21,11 @@ module CarrierWave
|
|
|
21
21
|
# process :resize_to_fit => [200, 200]
|
|
22
22
|
# end
|
|
23
23
|
#
|
|
24
|
-
# Or create your own helpers with the powerful
|
|
25
|
-
#
|
|
26
|
-
#
|
|
24
|
+
# Or create your own helpers with the powerful minimagick! method, which
|
|
25
|
+
# yields an ImageProcessing::Builder object. Check out the ImageProcessing
|
|
26
|
+
# docs at http://github.com/janko-m/image_processing and the list of all
|
|
27
|
+
# available ImageMagick options at
|
|
28
|
+
# http://www.imagemagick.org/script/command-line-options.php for more info.
|
|
27
29
|
#
|
|
28
30
|
# class MyUploader < CarrierWave::Uploader::Base
|
|
29
31
|
# include CarrierWave::MiniMagick
|
|
@@ -31,23 +33,22 @@ module CarrierWave
|
|
|
31
33
|
# process :radial_blur => 10
|
|
32
34
|
#
|
|
33
35
|
# def radial_blur(amount)
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
36
|
+
# minimagick! do |builder|
|
|
37
|
+
# builder.radial_blur(amount)
|
|
38
|
+
# builder = yield(builder) if block_given?
|
|
39
|
+
# builder
|
|
38
40
|
# end
|
|
39
41
|
# end
|
|
40
42
|
# end
|
|
41
43
|
#
|
|
42
44
|
# === Note
|
|
43
45
|
#
|
|
44
|
-
# MiniMagick
|
|
45
|
-
#
|
|
46
|
+
# The ImageProcessing gem uses MiniMagick, a mini replacement for RMagick
|
|
47
|
+
# that uses ImageMagick command-line tools, to build a "convert" command that
|
|
48
|
+
# performs the processing.
|
|
46
49
|
#
|
|
47
50
|
# You can find more information here:
|
|
48
51
|
#
|
|
49
|
-
# http://mini_magick.rubyforge.org/
|
|
50
|
-
# and
|
|
51
52
|
# https://github.com/minimagick/minimagick/
|
|
52
53
|
#
|
|
53
54
|
#
|
|
@@ -55,19 +56,7 @@ module CarrierWave
|
|
|
55
56
|
extend ActiveSupport::Concern
|
|
56
57
|
|
|
57
58
|
included do
|
|
58
|
-
|
|
59
|
-
require "mini_magick"
|
|
60
|
-
rescue LoadError => e
|
|
61
|
-
e.message << " (You may need to install the mini_magick gem)"
|
|
62
|
-
raise e
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
prepend Module.new {
|
|
66
|
-
def initialize(*)
|
|
67
|
-
super
|
|
68
|
-
@format = nil
|
|
69
|
-
end
|
|
70
|
-
}
|
|
59
|
+
require "image_processing/mini_magick"
|
|
71
60
|
end
|
|
72
61
|
|
|
73
62
|
module ClassMethods
|
|
@@ -90,6 +79,10 @@ module CarrierWave
|
|
|
90
79
|
def resize_and_pad(width, height, background=:transparent, gravity='Center')
|
|
91
80
|
process :resize_and_pad => [width, height, background, gravity]
|
|
92
81
|
end
|
|
82
|
+
|
|
83
|
+
def crop(left, top, width, height)
|
|
84
|
+
process :crop => [left, top, width, height]
|
|
85
|
+
end
|
|
93
86
|
end
|
|
94
87
|
|
|
95
88
|
##
|
|
@@ -99,7 +92,7 @@ module CarrierWave
|
|
|
99
92
|
#
|
|
100
93
|
# === Parameters
|
|
101
94
|
#
|
|
102
|
-
# [format (#to_s)] an
|
|
95
|
+
# [format (#to_s)] an abbreviation of the format
|
|
103
96
|
#
|
|
104
97
|
# === Yields
|
|
105
98
|
#
|
|
@@ -109,12 +102,11 @@ module CarrierWave
|
|
|
109
102
|
#
|
|
110
103
|
# image.convert(:png)
|
|
111
104
|
#
|
|
112
|
-
def convert(format, page=nil)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
img
|
|
105
|
+
def convert(format, page=nil, &block)
|
|
106
|
+
minimagick!(block) do |builder|
|
|
107
|
+
builder = builder.convert(format)
|
|
108
|
+
builder = builder.loader(page: page) if page
|
|
109
|
+
builder
|
|
118
110
|
end
|
|
119
111
|
end
|
|
120
112
|
|
|
@@ -128,21 +120,18 @@ module CarrierWave
|
|
|
128
120
|
#
|
|
129
121
|
# [width (Integer)] the width to scale the image to
|
|
130
122
|
# [height (Integer)] the height to scale the image to
|
|
123
|
+
# [combine_options (Hash)] additional ImageMagick options to apply before resizing
|
|
131
124
|
#
|
|
132
125
|
# === Yields
|
|
133
126
|
#
|
|
134
127
|
# [MiniMagick::Image] additional manipulations to perform
|
|
135
128
|
#
|
|
136
|
-
def resize_to_limit(width, height, combine_options: {})
|
|
137
|
-
width =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
append_combine_options cmd, combine_options
|
|
143
|
-
end
|
|
144
|
-
img = yield(img) if block_given?
|
|
145
|
-
img
|
|
129
|
+
def resize_to_limit(width, height, combine_options: {}, &block)
|
|
130
|
+
width, height = resolve_dimensions(width, height)
|
|
131
|
+
|
|
132
|
+
minimagick!(block) do |builder|
|
|
133
|
+
builder.resize_to_limit(width, height)
|
|
134
|
+
.apply(combine_options)
|
|
146
135
|
end
|
|
147
136
|
end
|
|
148
137
|
|
|
@@ -155,21 +144,18 @@ module CarrierWave
|
|
|
155
144
|
#
|
|
156
145
|
# [width (Integer)] the width to scale the image to
|
|
157
146
|
# [height (Integer)] the height to scale the image to
|
|
147
|
+
# [combine_options (Hash)] additional ImageMagick options to apply before resizing
|
|
158
148
|
#
|
|
159
149
|
# === Yields
|
|
160
150
|
#
|
|
161
151
|
# [MiniMagick::Image] additional manipulations to perform
|
|
162
152
|
#
|
|
163
|
-
def resize_to_fit(width, height, combine_options: {})
|
|
164
|
-
width =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
append_combine_options cmd, combine_options
|
|
170
|
-
end
|
|
171
|
-
img = yield(img) if block_given?
|
|
172
|
-
img
|
|
153
|
+
def resize_to_fit(width, height, combine_options: {}, &block)
|
|
154
|
+
width, height = resolve_dimensions(width, height)
|
|
155
|
+
|
|
156
|
+
minimagick!(block) do |builder|
|
|
157
|
+
builder.resize_to_fit(width, height)
|
|
158
|
+
.apply(combine_options)
|
|
173
159
|
end
|
|
174
160
|
end
|
|
175
161
|
|
|
@@ -183,37 +169,18 @@ module CarrierWave
|
|
|
183
169
|
# [width (Integer)] the width to scale the image to
|
|
184
170
|
# [height (Integer)] the height to scale the image to
|
|
185
171
|
# [gravity (String)] the current gravity suggestion (default: 'Center'; options: 'NorthWest', 'North', 'NorthEast', 'West', 'Center', 'East', 'SouthWest', 'South', 'SouthEast')
|
|
172
|
+
# [combine_options (Hash)] additional ImageMagick options to apply before resizing
|
|
186
173
|
#
|
|
187
174
|
# === Yields
|
|
188
175
|
#
|
|
189
176
|
# [MiniMagick::Image] additional manipulations to perform
|
|
190
177
|
#
|
|
191
|
-
def resize_to_fill(width, height, gravity = 'Center', combine_options: {})
|
|
192
|
-
width =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if width != cols || height != rows
|
|
198
|
-
scale_x = width/cols.to_f
|
|
199
|
-
scale_y = height/rows.to_f
|
|
200
|
-
if scale_x >= scale_y
|
|
201
|
-
cols = (scale_x * (cols + 0.5)).round
|
|
202
|
-
rows = (scale_x * (rows + 0.5)).round
|
|
203
|
-
cmd.resize "#{cols}"
|
|
204
|
-
else
|
|
205
|
-
cols = (scale_y * (cols + 0.5)).round
|
|
206
|
-
rows = (scale_y * (rows + 0.5)).round
|
|
207
|
-
cmd.resize "x#{rows}"
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
cmd.gravity gravity
|
|
211
|
-
cmd.background "rgba(255,255,255,0.0)"
|
|
212
|
-
cmd.extent "#{width}x#{height}" if cols != width || rows != height
|
|
213
|
-
append_combine_options cmd, combine_options
|
|
214
|
-
end
|
|
215
|
-
img = yield(img) if block_given?
|
|
216
|
-
img
|
|
178
|
+
def resize_to_fill(width, height, gravity = 'Center', combine_options: {}, &block)
|
|
179
|
+
width, height = resolve_dimensions(width, height)
|
|
180
|
+
|
|
181
|
+
minimagick!(block) do |builder|
|
|
182
|
+
builder.resize_to_fill(width, height, gravity: gravity)
|
|
183
|
+
.apply(combine_options)
|
|
217
184
|
end
|
|
218
185
|
end
|
|
219
186
|
|
|
@@ -232,28 +199,43 @@ module CarrierWave
|
|
|
232
199
|
# [height (Integer)] the height to scale the image to
|
|
233
200
|
# [background (String, :transparent)] the color of the background as a hexcode, like "#ff45de"
|
|
234
201
|
# [gravity (String)] how to position the image
|
|
202
|
+
# [combine_options (Hash)] additional ImageMagick options to apply before resizing
|
|
203
|
+
#
|
|
204
|
+
# === Yields
|
|
205
|
+
#
|
|
206
|
+
# [MiniMagick::Image] additional manipulations to perform
|
|
207
|
+
#
|
|
208
|
+
def resize_and_pad(width, height, background=:transparent, gravity='Center', combine_options: {}, &block)
|
|
209
|
+
width, height = resolve_dimensions(width, height)
|
|
210
|
+
|
|
211
|
+
minimagick!(block) do |builder|
|
|
212
|
+
builder.resize_and_pad(width, height, background: background, gravity: gravity)
|
|
213
|
+
.apply(combine_options)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
##
|
|
218
|
+
# Crop the image to the contents of a box positioned at [left] and [top], with the dimensions given
|
|
219
|
+
# by [width] and [height]. The original image bottom/right edge is preserved if the cropping box falls
|
|
220
|
+
# outside the image bounds.
|
|
221
|
+
#
|
|
222
|
+
# === Parameters
|
|
223
|
+
#
|
|
224
|
+
# [left (integer)] left edge of area to extract
|
|
225
|
+
# [top (integer)] top edge of area to extract
|
|
226
|
+
# [width (Integer)] width of area to extract
|
|
227
|
+
# [height (Integer)] height of area to extract
|
|
235
228
|
#
|
|
236
229
|
# === Yields
|
|
237
230
|
#
|
|
238
231
|
# [MiniMagick::Image] additional manipulations to perform
|
|
239
232
|
#
|
|
240
|
-
def
|
|
241
|
-
width =
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if background == :transparent
|
|
247
|
-
cmd.background "rgba(255, 255, 255, 0.0)"
|
|
248
|
-
else
|
|
249
|
-
cmd.background background
|
|
250
|
-
end
|
|
251
|
-
cmd.gravity gravity
|
|
252
|
-
cmd.extent "#{width}x#{height}"
|
|
253
|
-
append_combine_options cmd, combine_options
|
|
254
|
-
end
|
|
255
|
-
img = yield(img) if block_given?
|
|
256
|
-
img
|
|
233
|
+
def crop(left, top, width, height, combine_options: {}, &block)
|
|
234
|
+
width, height = resolve_dimensions(width, height)
|
|
235
|
+
|
|
236
|
+
minimagick!(block) do |builder|
|
|
237
|
+
builder.crop(left, top, width, height)
|
|
238
|
+
.apply(combine_options)
|
|
257
239
|
end
|
|
258
240
|
end
|
|
259
241
|
|
|
@@ -284,6 +266,9 @@ module CarrierWave
|
|
|
284
266
|
# and then pass each of its frames to the supplied block. It will then
|
|
285
267
|
# save the image to disk.
|
|
286
268
|
#
|
|
269
|
+
# NOTE: This method exists mostly for backwards compatibility, you should
|
|
270
|
+
# probably use #minimagick!.
|
|
271
|
+
#
|
|
287
272
|
# === Gotcha
|
|
288
273
|
#
|
|
289
274
|
# This method assumes that the object responds to +current_path+.
|
|
@@ -303,46 +288,75 @@ module CarrierWave
|
|
|
303
288
|
cache_stored_file! if !cached?
|
|
304
289
|
image = ::MiniMagick::Image.open(current_path)
|
|
305
290
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
image = yield(image)
|
|
309
|
-
image.write(current_path)
|
|
310
|
-
|
|
311
|
-
if @format
|
|
312
|
-
move_to = current_path.chomp(File.extname(current_path)) + ".#{@format}"
|
|
313
|
-
file.content_type = ::MIME::Types.type_for(move_to).first.to_s
|
|
314
|
-
file.move_to(move_to, permissions, directory_permissions)
|
|
315
|
-
end
|
|
291
|
+
image = yield(image)
|
|
292
|
+
FileUtils.mv image.path, current_path
|
|
316
293
|
|
|
317
|
-
|
|
318
|
-
ensure
|
|
319
|
-
image.destroy!
|
|
320
|
-
end
|
|
294
|
+
::MiniMagick::Image.new(current_path).identify
|
|
321
295
|
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
|
322
|
-
message
|
|
296
|
+
raise e if e.message =~ /(You must have .+ installed|is not installed|executable not found|delegate failed)/
|
|
297
|
+
message = I18n.translate(:"errors.messages.processing_error")
|
|
323
298
|
raise CarrierWave::ProcessingError, message
|
|
299
|
+
ensure
|
|
300
|
+
image.destroy! if image
|
|
324
301
|
end
|
|
325
302
|
|
|
326
|
-
|
|
303
|
+
# Process the image with MiniMagick, using the ImageProcessing gem. This
|
|
304
|
+
# method will build a "convert" ImageMagick command and execute it on the
|
|
305
|
+
# current image.
|
|
306
|
+
#
|
|
307
|
+
# === Gotcha
|
|
308
|
+
#
|
|
309
|
+
# This method assumes that the object responds to +current_path+.
|
|
310
|
+
# Any class that this module is mixed into must have a +current_path+ method.
|
|
311
|
+
# CarrierWave::Uploader does, so you won't need to worry about this in
|
|
312
|
+
# most cases.
|
|
313
|
+
#
|
|
314
|
+
# === Yields
|
|
315
|
+
#
|
|
316
|
+
# [ImageProcessing::Builder] use it to define processing to be performed
|
|
317
|
+
#
|
|
318
|
+
# === Raises
|
|
319
|
+
#
|
|
320
|
+
# [CarrierWave::ProcessingError] if processing failed.
|
|
321
|
+
def minimagick!(block = nil)
|
|
322
|
+
builder = ImageProcessing::MiniMagick.source(current_path)
|
|
323
|
+
builder = yield(builder)
|
|
324
|
+
|
|
325
|
+
result = builder.call
|
|
326
|
+
result.close
|
|
327
327
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
cmd.send(method, options)
|
|
334
|
-
end
|
|
335
|
-
end
|
|
328
|
+
# backwards compatibility (we want to eventually move away from MiniMagick::Image)
|
|
329
|
+
if block
|
|
330
|
+
image = ::MiniMagick::Image.new(result.path, result)
|
|
331
|
+
image = block.call(image)
|
|
332
|
+
result = image.instance_variable_get(:@tempfile)
|
|
336
333
|
end
|
|
337
334
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
335
|
+
FileUtils.mv result.path, current_path
|
|
336
|
+
|
|
337
|
+
if File.extname(result.path) != File.extname(current_path)
|
|
338
|
+
move_to = current_path.chomp(File.extname(current_path)) + File.extname(result.path)
|
|
339
|
+
file.content_type = Marcel::Magic.by_path(move_to).try(:type)
|
|
340
|
+
file.move_to(move_to, permissions, directory_permissions)
|
|
341
341
|
end
|
|
342
|
+
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
|
343
|
+
raise e if e.message =~ /(You must have .+ installed|is not installed|executable not found)/
|
|
344
|
+
message = I18n.translate(:"errors.messages.processing_error")
|
|
345
|
+
raise CarrierWave::ProcessingError, message
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
private
|
|
342
349
|
|
|
343
|
-
|
|
344
|
-
|
|
350
|
+
def resolve_dimensions(*dimensions)
|
|
351
|
+
dimensions.map do |value|
|
|
352
|
+
next value unless value.instance_of?(Proc)
|
|
353
|
+
value.arity >= 1 ? value.call(self) : value.call
|
|
345
354
|
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def mini_magick_image
|
|
358
|
+
::MiniMagick::Image.read(read)
|
|
359
|
+
end
|
|
346
360
|
|
|
347
361
|
end # MiniMagick
|
|
348
362
|
end # CarrierWave
|
|
@@ -22,7 +22,7 @@ module CarrierWave
|
|
|
22
22
|
# end
|
|
23
23
|
#
|
|
24
24
|
# Or create your own helpers with the powerful manipulate! method. Check
|
|
25
|
-
# out the RMagick docs at
|
|
25
|
+
# out the RMagick docs at https://rmagick.github.io/ for more
|
|
26
26
|
# info
|
|
27
27
|
#
|
|
28
28
|
# class MyUploader < CarrierWave::Uploader::Base
|
|
@@ -62,10 +62,12 @@ module CarrierWave
|
|
|
62
62
|
begin
|
|
63
63
|
require "rmagick"
|
|
64
64
|
rescue LoadError
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
begin
|
|
66
|
+
require "RMagick"
|
|
67
|
+
rescue LoadError => e
|
|
68
|
+
e.message << " (You may need to install the rmagick gem)"
|
|
69
|
+
raise e
|
|
70
|
+
end
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
prepend Module.new {
|
|
@@ -100,16 +102,20 @@ module CarrierWave
|
|
|
100
102
|
def resize_to_geometry_string(geometry_string)
|
|
101
103
|
process :resize_to_geometry_string => [geometry_string]
|
|
102
104
|
end
|
|
105
|
+
|
|
106
|
+
def crop(left, top, width, height)
|
|
107
|
+
process :crop => [left, top, width, height]
|
|
108
|
+
end
|
|
103
109
|
end
|
|
104
110
|
|
|
105
111
|
##
|
|
106
112
|
# Changes the image encoding format to the given format
|
|
107
113
|
#
|
|
108
|
-
# See even
|
|
114
|
+
# See even https://rmagick.github.io/magick.html#formats
|
|
109
115
|
#
|
|
110
116
|
# === Parameters
|
|
111
117
|
#
|
|
112
|
-
# [format (#to_s)] an
|
|
118
|
+
# [format (#to_s)] an abbreviation of the format
|
|
113
119
|
#
|
|
114
120
|
# === Yields
|
|
115
121
|
#
|
|
@@ -159,7 +165,7 @@ module CarrierWave
|
|
|
159
165
|
# image may be shorter or narrower than specified in the smaller dimension
|
|
160
166
|
# but will not be larger than the specified values."
|
|
161
167
|
#
|
|
162
|
-
# See even
|
|
168
|
+
# See even https://rmagick.github.io/image3.html#resize_to_fit
|
|
163
169
|
#
|
|
164
170
|
# === Parameters
|
|
165
171
|
#
|
|
@@ -185,7 +191,7 @@ module CarrierWave
|
|
|
185
191
|
# specified dimensions while retaining the aspect ratio of the original
|
|
186
192
|
# image. If necessary, crop the image in the larger dimension."
|
|
187
193
|
#
|
|
188
|
-
# See even
|
|
194
|
+
# See even https://rmagick.github.io/image3.html#resize_to_fill
|
|
189
195
|
#
|
|
190
196
|
# === Parameters
|
|
191
197
|
#
|
|
@@ -228,13 +234,7 @@ module CarrierWave
|
|
|
228
234
|
height = dimension_from height
|
|
229
235
|
manipulate! do |img|
|
|
230
236
|
img.resize_to_fit!(width, height)
|
|
231
|
-
|
|
232
|
-
if background == :transparent
|
|
233
|
-
filled = new_img.matte_floodfill(1, 1)
|
|
234
|
-
else
|
|
235
|
-
filled = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
|
|
236
|
-
end
|
|
237
|
-
destroy_image(new_img)
|
|
237
|
+
filled = ::Magick::Image.new(width, height) { |image| image.background_color = background == :transparent ? 'rgba(255,255,255,0)' : background.to_s }
|
|
238
238
|
filled.composite!(img, gravity, ::Magick::OverCompositeOp)
|
|
239
239
|
destroy_image(img)
|
|
240
240
|
filled = yield(filled) if block_given?
|
|
@@ -264,6 +264,33 @@ module CarrierWave
|
|
|
264
264
|
end
|
|
265
265
|
end
|
|
266
266
|
|
|
267
|
+
##
|
|
268
|
+
# Crop the image to the contents of a box positioned at [left] and [top], with the dimensions given
|
|
269
|
+
# by [width] and [height]. The original image bottom/right edge is preserved if the cropping box falls
|
|
270
|
+
# outside the image bounds.
|
|
271
|
+
#
|
|
272
|
+
# === Parameters
|
|
273
|
+
#
|
|
274
|
+
# [left (integer)] left edge of area to extract
|
|
275
|
+
# [top (integer)] top edge of area to extract
|
|
276
|
+
# [width (Integer)] width of area to extract
|
|
277
|
+
# [height (Integer)] height of area to extract
|
|
278
|
+
#
|
|
279
|
+
# === Yields
|
|
280
|
+
#
|
|
281
|
+
# [Magick::Image] additional manipulations to perform
|
|
282
|
+
#
|
|
283
|
+
def crop(left, top, width, height, combine_options: {})
|
|
284
|
+
width = dimension_from width
|
|
285
|
+
height = dimension_from height
|
|
286
|
+
|
|
287
|
+
manipulate! do |img|
|
|
288
|
+
img.crop!(left, top, width, height)
|
|
289
|
+
img = yield(img) if block_given?
|
|
290
|
+
img
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
267
294
|
##
|
|
268
295
|
# Returns the width of the image.
|
|
269
296
|
#
|
|
@@ -363,15 +390,15 @@ module CarrierWave
|
|
|
363
390
|
if options[:format] || @format
|
|
364
391
|
frames.write("#{options[:format] || @format}:#{current_path}", &write_block)
|
|
365
392
|
move_to = current_path.chomp(File.extname(current_path)) + ".#{options[:format] || @format}"
|
|
366
|
-
file.content_type = ::
|
|
393
|
+
file.content_type = Marcel::Magic.by_path(move_to).try(:type)
|
|
367
394
|
file.move_to(move_to, permissions, directory_permissions)
|
|
368
395
|
else
|
|
369
396
|
frames.write(current_path, &write_block)
|
|
370
397
|
end
|
|
371
398
|
|
|
372
399
|
destroy_image(frames)
|
|
373
|
-
rescue ::Magick::ImageMagickError
|
|
374
|
-
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.
|
|
400
|
+
rescue ::Magick::ImageMagickError
|
|
401
|
+
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.processing_error")
|
|
375
402
|
end
|
|
376
403
|
|
|
377
404
|
private
|
|
@@ -381,7 +408,7 @@ module CarrierWave
|
|
|
381
408
|
proc do |img|
|
|
382
409
|
options.each do |k, v|
|
|
383
410
|
if v.is_a?(String) && (matches = v.match(/^["'](.+)["']/))
|
|
384
|
-
|
|
411
|
+
CarrierWave.deprecator.warn "Passing quoted strings like #{v} to #manipulate! is deprecated, pass them without quoting."
|
|
385
412
|
v = matches[1]
|
|
386
413
|
end
|
|
387
414
|
img.public_send(:"#{k}=", v)
|