plowdawg-carrierwave 0.5.8
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/README.md +674 -0
- data/lib/carrierwave.rb +109 -0
- data/lib/carrierwave/compatibility/paperclip.rb +95 -0
- data/lib/carrierwave/locale/en.yml +5 -0
- data/lib/carrierwave/mount.rb +382 -0
- data/lib/carrierwave/orm/activerecord.rb +46 -0
- data/lib/carrierwave/processing/mime_types.rb +58 -0
- data/lib/carrierwave/processing/mini_magick.rb +253 -0
- data/lib/carrierwave/processing/rmagick.rb +279 -0
- data/lib/carrierwave/sanitized_file.rb +302 -0
- data/lib/carrierwave/storage/abstract.rb +30 -0
- data/lib/carrierwave/storage/cloud_files.rb +188 -0
- data/lib/carrierwave/storage/file.rb +47 -0
- data/lib/carrierwave/storage/fog.rb +332 -0
- data/lib/carrierwave/storage/right_s3.rb +1 -0
- data/lib/carrierwave/storage/s3.rb +240 -0
- data/lib/carrierwave/test/matchers.rb +164 -0
- data/lib/carrierwave/uploader.rb +44 -0
- data/lib/carrierwave/uploader/cache.rb +160 -0
- data/lib/carrierwave/uploader/callbacks.rb +35 -0
- data/lib/carrierwave/uploader/configuration.rb +162 -0
- data/lib/carrierwave/uploader/default_url.rb +19 -0
- data/lib/carrierwave/uploader/download.rb +75 -0
- data/lib/carrierwave/uploader/extension_whitelist.rb +49 -0
- data/lib/carrierwave/uploader/mountable.rb +39 -0
- data/lib/carrierwave/uploader/processing.rb +90 -0
- data/lib/carrierwave/uploader/proxy.rb +77 -0
- data/lib/carrierwave/uploader/remove.rb +23 -0
- data/lib/carrierwave/uploader/store.rb +113 -0
- data/lib/carrierwave/uploader/url.rb +45 -0
- data/lib/carrierwave/uploader/versions.rb +237 -0
- data/lib/carrierwave/validations/active_model.rb +79 -0
- data/lib/carrierwave/version.rb +3 -0
- data/lib/generators/templates/uploader.rb +49 -0
- data/lib/generators/uploader_generator.rb +7 -0
- metadata +215 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'carrierwave/validations/active_model'
|
5
|
+
|
6
|
+
module CarrierWave
|
7
|
+
module ActiveRecord
|
8
|
+
|
9
|
+
include CarrierWave::Mount
|
10
|
+
|
11
|
+
##
|
12
|
+
# See +CarrierWave::Mount#mount_uploader+ for documentation
|
13
|
+
#
|
14
|
+
def mount_uploader(column, uploader=nil, options={}, &block)
|
15
|
+
super
|
16
|
+
|
17
|
+
alias_method :read_uploader, :read_attribute
|
18
|
+
alias_method :write_uploader, :write_attribute
|
19
|
+
public :read_uploader
|
20
|
+
public :write_uploader
|
21
|
+
|
22
|
+
include CarrierWave::Validations::ActiveModel
|
23
|
+
|
24
|
+
validates_integrity_of column if uploader_option(column.to_sym, :validate_integrity)
|
25
|
+
validates_processing_of column if uploader_option(column.to_sym, :validate_processing)
|
26
|
+
|
27
|
+
after_save :"store_#{column}!"
|
28
|
+
before_save :"write_#{column}_identifier"
|
29
|
+
after_destroy :"remove_#{column}!"
|
30
|
+
before_update :"store_previous_model_for_#{column}"
|
31
|
+
after_save :"remove_previously_stored_#{column}"
|
32
|
+
|
33
|
+
class_eval <<-RUBY, __FILE__, __LINE__+1
|
34
|
+
def #{column}=(new_file)
|
35
|
+
column = _mounter(:#{column}).serialization_column
|
36
|
+
send(:"\#{column}_will_change!")
|
37
|
+
super
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end # ActiveRecord
|
44
|
+
end # CarrierWave
|
45
|
+
|
46
|
+
ActiveRecord::Base.extend CarrierWave::ActiveRecord
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'mime/types'
|
2
|
+
|
3
|
+
module CarrierWave
|
4
|
+
|
5
|
+
##
|
6
|
+
# This module simplifies the use of the mime-types gem to intelligently
|
7
|
+
# guess and set the content-type of a file. If you want to use this, you'll
|
8
|
+
# need to require this file:
|
9
|
+
#
|
10
|
+
# require 'carrierwave/processing/mime_types'
|
11
|
+
#
|
12
|
+
# And then include it in your uploader:
|
13
|
+
#
|
14
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
15
|
+
# include CarrierWave::MimeTypes
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# You can now use the provided helper:
|
19
|
+
#
|
20
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
21
|
+
# include CarrierWave::MimeTypes
|
22
|
+
#
|
23
|
+
# process :set_content_type
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
module MimeTypes
|
27
|
+
extend ActiveSupport::Concern
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def set_content_type(override=false)
|
31
|
+
process :set_content_type => override
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Changes the file content_type using the mime-types gem
|
37
|
+
#
|
38
|
+
# === Parameters
|
39
|
+
#
|
40
|
+
# [override (Boolean)] whether or not to override the file's content_type
|
41
|
+
# if it is already set and not a generic content-type,
|
42
|
+
# false by default
|
43
|
+
#
|
44
|
+
def set_content_type(override=false)
|
45
|
+
if override || file.content_type.blank? || file.content_type == 'application/octet-stream'
|
46
|
+
new_content_type = ::MIME::Types.type_for(file.original_filename).first.to_s
|
47
|
+
if file.respond_to?(:content_type=)
|
48
|
+
file.content_type = new_content_type
|
49
|
+
else
|
50
|
+
file.set_instance_variable(:@content_type, new_content_type)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
rescue ::MIME::InvalidContentType => e
|
54
|
+
raise CarrierWave::ProcessingError.new("Failed to process file with MIME::Types, maybe not valid content-type? Original Error: #{e}")
|
55
|
+
end
|
56
|
+
|
57
|
+
end # MimeTypes
|
58
|
+
end # CarrierWave
|
@@ -0,0 +1,253 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'mini_magick'
|
4
|
+
|
5
|
+
module CarrierWave
|
6
|
+
|
7
|
+
##
|
8
|
+
# This module simplifies manipulation with MiniMagick by providing a set
|
9
|
+
# of convenient helper methods. If you want to use them, you'll need to
|
10
|
+
# require this file:
|
11
|
+
#
|
12
|
+
# require 'carrierwave/processing/mini_magick'
|
13
|
+
#
|
14
|
+
# And then include it in your uploader:
|
15
|
+
#
|
16
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
17
|
+
# include CarrierWave::MiniMagick
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# You can now use the provided helpers:
|
21
|
+
#
|
22
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
23
|
+
# include CarrierWave::MiniMagick
|
24
|
+
#
|
25
|
+
# process :resize_to_fit => [200, 200]
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Or create your own helpers with the powerful manipulate! method. Check
|
29
|
+
# out the ImageMagick docs at http://www.imagemagick.org/script/command-line-options.php for more
|
30
|
+
# info
|
31
|
+
#
|
32
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
33
|
+
# include CarrierWave::MiniMagick
|
34
|
+
#
|
35
|
+
# process :do_stuff => 10.0
|
36
|
+
#
|
37
|
+
# def do_stuff(blur_factor)
|
38
|
+
# manipulate! do |img|
|
39
|
+
# img = img.sepiatone
|
40
|
+
# img = img.auto_orient
|
41
|
+
# img = img.radial_blur blur_factor
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# === Note
|
47
|
+
#
|
48
|
+
# MiniMagick is a mini replacement for RMagick that uses the command line
|
49
|
+
# tool "mogrify" for image manipulation.
|
50
|
+
#
|
51
|
+
# You can find more information here:
|
52
|
+
#
|
53
|
+
# http://mini_magick.rubyforge.org/
|
54
|
+
# and
|
55
|
+
# http://github.com/probablycorey/mini_magick/
|
56
|
+
#
|
57
|
+
#
|
58
|
+
module MiniMagick
|
59
|
+
extend ActiveSupport::Concern
|
60
|
+
|
61
|
+
module ClassMethods
|
62
|
+
def convert(format)
|
63
|
+
process :convert => format
|
64
|
+
end
|
65
|
+
|
66
|
+
def resize_to_limit(width, height)
|
67
|
+
process :resize_to_limit => [width, height]
|
68
|
+
end
|
69
|
+
|
70
|
+
def resize_to_fit(width, height)
|
71
|
+
process :resize_to_fit => [width, height]
|
72
|
+
end
|
73
|
+
|
74
|
+
def resize_to_fill(width, height)
|
75
|
+
process :resize_to_fill => [width, height]
|
76
|
+
end
|
77
|
+
|
78
|
+
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
79
|
+
process :resize_and_pad => [width, height, background, gravity]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Changes the image encoding format to the given format
|
85
|
+
#
|
86
|
+
# See http://www.imagemagick.org/script/command-line-options.php#format
|
87
|
+
#
|
88
|
+
# === Parameters
|
89
|
+
#
|
90
|
+
# [format (#to_s)] an abreviation of the format
|
91
|
+
#
|
92
|
+
# === Yields
|
93
|
+
#
|
94
|
+
# [MiniMagick::Image] additional manipulations to perform
|
95
|
+
#
|
96
|
+
# === Examples
|
97
|
+
#
|
98
|
+
# image.convert(:png)
|
99
|
+
#
|
100
|
+
def convert(format)
|
101
|
+
manipulate! do |img|
|
102
|
+
img.format(format.to_s.downcase)
|
103
|
+
img = yield(img) if block_given?
|
104
|
+
img
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Resize the image to fit within the specified dimensions while retaining
|
110
|
+
# the original aspect ratio. Will only resize the image if it is larger than the
|
111
|
+
# specified dimensions. The resulting image may be shorter or narrower than specified
|
112
|
+
# in the smaller dimension but will not be larger than the specified values.
|
113
|
+
#
|
114
|
+
# === Parameters
|
115
|
+
#
|
116
|
+
# [width (Integer)] the width to scale the image to
|
117
|
+
# [height (Integer)] the height to scale the image to
|
118
|
+
#
|
119
|
+
# === Yields
|
120
|
+
#
|
121
|
+
# [MiniMagick::Image] additional manipulations to perform
|
122
|
+
#
|
123
|
+
def resize_to_limit(width, height)
|
124
|
+
manipulate! do |img|
|
125
|
+
img.resize "#{width}x#{height}>"
|
126
|
+
img = yield(img) if block_given?
|
127
|
+
img
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Resize the image to fit within the specified dimensions while retaining
|
133
|
+
# the original aspect ratio. The image may be shorter or narrower than
|
134
|
+
# specified in the smaller dimension but will not be larger than the specified values.
|
135
|
+
#
|
136
|
+
# === Parameters
|
137
|
+
#
|
138
|
+
# [width (Integer)] the width to scale the image to
|
139
|
+
# [height (Integer)] the height to scale the image to
|
140
|
+
#
|
141
|
+
# === Yields
|
142
|
+
#
|
143
|
+
# [MiniMagick::Image] additional manipulations to perform
|
144
|
+
#
|
145
|
+
def resize_to_fit(width, height)
|
146
|
+
manipulate! do |img|
|
147
|
+
img.resize "#{width}x#{height}"
|
148
|
+
img = yield(img) if block_given?
|
149
|
+
img
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Resize the image to fit within the specified dimensions while retaining
|
155
|
+
# the aspect ratio of the original image. If necessary, crop the image in the
|
156
|
+
# larger dimension.
|
157
|
+
#
|
158
|
+
# === Parameters
|
159
|
+
#
|
160
|
+
# [width (Integer)] the width to scale the image to
|
161
|
+
# [height (Integer)] the height to scale the image to
|
162
|
+
#
|
163
|
+
# === Yields
|
164
|
+
#
|
165
|
+
# [MiniMagick::Image] additional manipulations to perform
|
166
|
+
#
|
167
|
+
def resize_to_fill(width, height, gravity = 'Center')
|
168
|
+
manipulate! do |img|
|
169
|
+
cols, rows = img[:dimensions]
|
170
|
+
img.combine_options do |cmd|
|
171
|
+
if width != cols || height != rows
|
172
|
+
scale = [width/cols.to_f, height/rows.to_f].max
|
173
|
+
cols = (scale * (cols + 0.5)).round
|
174
|
+
rows = (scale * (rows + 0.5)).round
|
175
|
+
cmd.resize "#{cols}x#{rows}"
|
176
|
+
end
|
177
|
+
cmd.gravity gravity
|
178
|
+
cmd.extent "#{width}x#{height}" if cols != width || rows != height
|
179
|
+
end
|
180
|
+
img = yield(img) if block_given?
|
181
|
+
img
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# Resize the image to fit within the specified dimensions while retaining
|
187
|
+
# the original aspect ratio. If necessary, will pad the remaining area
|
188
|
+
# with the given color, which defaults to transparent (for gif and png,
|
189
|
+
# white for jpeg).
|
190
|
+
#
|
191
|
+
# See http://www.imagemagick.org/script/command-line-options.php#gravity
|
192
|
+
# for gravity options.
|
193
|
+
#
|
194
|
+
# === Parameters
|
195
|
+
#
|
196
|
+
# [width (Integer)] the width to scale the image to
|
197
|
+
# [height (Integer)] the height to scale the image to
|
198
|
+
# [background (String, :transparent)] the color of the background as a hexcode, like "#ff45de"
|
199
|
+
# [gravity (String)] how to position the image
|
200
|
+
#
|
201
|
+
# === Yields
|
202
|
+
#
|
203
|
+
# [MiniMagick::Image] additional manipulations to perform
|
204
|
+
#
|
205
|
+
def resize_and_pad(width, height, background=:transparent, gravity='Center')
|
206
|
+
manipulate! do |img|
|
207
|
+
img.combine_options do |cmd|
|
208
|
+
cmd.thumbnail "#{width}x#{height}>"
|
209
|
+
if background == :transparent
|
210
|
+
cmd.background "rgba(0, 0, 0, 0.0)"
|
211
|
+
else
|
212
|
+
cmd.background background
|
213
|
+
end
|
214
|
+
cmd.gravity gravity
|
215
|
+
cmd.extent "#{width}x#{height}"
|
216
|
+
end
|
217
|
+
img = yield(img) if block_given?
|
218
|
+
img
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Manipulate the image with MiniMagick. This method will load up an image
|
224
|
+
# and then pass each of its frames to the supplied block. It will then
|
225
|
+
# save the image to disk.
|
226
|
+
#
|
227
|
+
# === Gotcha
|
228
|
+
#
|
229
|
+
# This method assumes that the object responds to +current_path+.
|
230
|
+
# Any class that this module is mixed into must have a +current_path+ method.
|
231
|
+
# CarrierWave::Uploader does, so you won't need to worry about this in
|
232
|
+
# most cases.
|
233
|
+
#
|
234
|
+
# === Yields
|
235
|
+
#
|
236
|
+
# [MiniMagick::Image] manipulations to perform
|
237
|
+
#
|
238
|
+
# === Raises
|
239
|
+
#
|
240
|
+
# [CarrierWave::ProcessingError] if manipulation failed.
|
241
|
+
#
|
242
|
+
def manipulate!
|
243
|
+
cache_stored_file! if !cached?
|
244
|
+
image = ::MiniMagick::Image.open(current_path)
|
245
|
+
image = yield(image)
|
246
|
+
image.write(current_path)
|
247
|
+
::MiniMagick::Image.open(current_path)
|
248
|
+
rescue ::MiniMagick::Error, ::MiniMagick::Invalid => e
|
249
|
+
raise CarrierWave::ProcessingError.new("Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: #{e}")
|
250
|
+
end
|
251
|
+
|
252
|
+
end # MiniMagick
|
253
|
+
end # CarrierWave
|
@@ -0,0 +1,279 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
unless defined? Magick
|
4
|
+
begin
|
5
|
+
require 'rmagick'
|
6
|
+
rescue LoadError
|
7
|
+
require 'RMagick'
|
8
|
+
rescue LoadError
|
9
|
+
puts "WARNING: Failed to require rmagick, image processing may fail!"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module CarrierWave
|
14
|
+
|
15
|
+
##
|
16
|
+
# This module simplifies manipulation with RMagick by providing a set
|
17
|
+
# of convenient helper methods. If you want to use them, you'll need to
|
18
|
+
# require this file:
|
19
|
+
#
|
20
|
+
# require 'carrierwave/processing/rmagick'
|
21
|
+
#
|
22
|
+
# And then include it in your uploader:
|
23
|
+
#
|
24
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
25
|
+
# include CarrierWave::RMagick
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# You can now use the provided helpers:
|
29
|
+
#
|
30
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
31
|
+
# include CarrierWave::RMagick
|
32
|
+
#
|
33
|
+
# process :resize_to_fit => [200, 200]
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# Or create your own helpers with the powerful manipulate! method. Check
|
37
|
+
# out the RMagick docs at http://www.imagemagick.org/RMagick/doc/ for more
|
38
|
+
# info
|
39
|
+
#
|
40
|
+
# class MyUploader < CarrierWave::Uploader::Base
|
41
|
+
# include CarrierWave::RMagick
|
42
|
+
#
|
43
|
+
# process :do_stuff => 10.0
|
44
|
+
#
|
45
|
+
# def do_stuff(blur_factor)
|
46
|
+
# manipulate! do |img|
|
47
|
+
# img = img.sepiatone
|
48
|
+
# img = img.auto_orient
|
49
|
+
# img = img.radial_blur(blur_factor)
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# === Note
|
55
|
+
#
|
56
|
+
# You should be aware how RMagick handles memory. manipulate! takes care
|
57
|
+
# of freeing up memory for you, but for optimum memory usage you should
|
58
|
+
# use destructive operations as much as possible:
|
59
|
+
#
|
60
|
+
# DON'T DO THIS:
|
61
|
+
# img = img.resize_to_fit
|
62
|
+
#
|
63
|
+
# DO THIS INSTEAD:
|
64
|
+
# img.resize_to_fit!
|
65
|
+
#
|
66
|
+
# Read this for more information why:
|
67
|
+
#
|
68
|
+
# http://rubyforge.org/forum/forum.php?thread_id=1374&forum_id=1618
|
69
|
+
#
|
70
|
+
module RMagick
|
71
|
+
extend ActiveSupport::Concern
|
72
|
+
|
73
|
+
module ClassMethods
|
74
|
+
def convert(format)
|
75
|
+
process :convert => format
|
76
|
+
end
|
77
|
+
|
78
|
+
def resize_to_limit(width, height)
|
79
|
+
process :resize_to_limit => [width, height]
|
80
|
+
end
|
81
|
+
|
82
|
+
def resize_to_fit(width, height)
|
83
|
+
process :resize_to_fit => [width, height]
|
84
|
+
end
|
85
|
+
|
86
|
+
def resize_to_fill(width, height, gravity=::Magick::CenterGravity)
|
87
|
+
process :resize_to_fill => [width, height, gravity]
|
88
|
+
end
|
89
|
+
|
90
|
+
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
91
|
+
process :resize_and_pad => [width, height, background, gravity]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Changes the image encoding format to the given format
|
97
|
+
#
|
98
|
+
# See even http://www.imagemagick.org/RMagick/doc/magick.html#formats
|
99
|
+
#
|
100
|
+
# === Parameters
|
101
|
+
#
|
102
|
+
# [format (#to_s)] an abreviation of the format
|
103
|
+
#
|
104
|
+
# === Yields
|
105
|
+
#
|
106
|
+
# [Magick::Image] additional manipulations to perform
|
107
|
+
#
|
108
|
+
# === Examples
|
109
|
+
#
|
110
|
+
# image.convert(:png)
|
111
|
+
#
|
112
|
+
def convert(format)
|
113
|
+
manipulate!(:format => format)
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Resize the image to fit within the specified dimensions while retaining
|
118
|
+
# the original aspect ratio. Will only resize the image if it is larger than the
|
119
|
+
# specified dimensions. The resulting image may be shorter or narrower than specified
|
120
|
+
# in the smaller dimension but will not be larger than the specified values.
|
121
|
+
#
|
122
|
+
# === Parameters
|
123
|
+
#
|
124
|
+
# [width (Integer)] the width to scale the image to
|
125
|
+
# [height (Integer)] the height to scale the image to
|
126
|
+
#
|
127
|
+
# === Yields
|
128
|
+
#
|
129
|
+
# [Magick::Image] additional manipulations to perform
|
130
|
+
#
|
131
|
+
def resize_to_limit(width, height)
|
132
|
+
manipulate! do |img|
|
133
|
+
geometry = Magick::Geometry.new(width, height, 0, 0, Magick::GreaterGeometry)
|
134
|
+
new_img = img.change_geometry(geometry) do |new_width, new_height|
|
135
|
+
img.resize(new_width, new_height)
|
136
|
+
end
|
137
|
+
destroy_image(img)
|
138
|
+
new_img = yield(new_img) if block_given?
|
139
|
+
new_img
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# From the RMagick documentation: "Resize the image to fit within the
|
145
|
+
# specified dimensions while retaining the original aspect ratio. The
|
146
|
+
# image may be shorter or narrower than specified in the smaller dimension
|
147
|
+
# but will not be larger than the specified values."
|
148
|
+
#
|
149
|
+
# See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fit
|
150
|
+
#
|
151
|
+
# === Parameters
|
152
|
+
#
|
153
|
+
# [width (Integer)] the width to scale the image to
|
154
|
+
# [height (Integer)] the height to scale the image to
|
155
|
+
#
|
156
|
+
# === Yields
|
157
|
+
#
|
158
|
+
# [Magick::Image] additional manipulations to perform
|
159
|
+
#
|
160
|
+
def resize_to_fit(width, height)
|
161
|
+
manipulate! do |img|
|
162
|
+
img.resize_to_fit!(width, height)
|
163
|
+
img = yield(img) if block_given?
|
164
|
+
img
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# From the RMagick documentation: "Resize the image to fit within the
|
170
|
+
# specified dimensions while retaining the aspect ratio of the original
|
171
|
+
# image. If necessary, crop the image in the larger dimension."
|
172
|
+
#
|
173
|
+
# See even http://www.imagemagick.org/RMagick/doc/image3.html#resize_to_fill
|
174
|
+
#
|
175
|
+
# === Parameters
|
176
|
+
#
|
177
|
+
# [width (Integer)] the width to scale the image to
|
178
|
+
# [height (Integer)] the height to scale the image to
|
179
|
+
#
|
180
|
+
# === Yields
|
181
|
+
#
|
182
|
+
# [Magick::Image] additional manipulations to perform
|
183
|
+
#
|
184
|
+
def resize_to_fill(width, height, gravity=::Magick::CenterGravity)
|
185
|
+
manipulate! do |img|
|
186
|
+
img.crop_resized!(width, height, gravity)
|
187
|
+
img = yield(img) if block_given?
|
188
|
+
img
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Resize the image to fit within the specified dimensions while retaining
|
194
|
+
# the original aspect ratio. If necessary, will pad the remaining area
|
195
|
+
# with the given color, which defaults to transparent (for gif and png,
|
196
|
+
# white for jpeg).
|
197
|
+
#
|
198
|
+
# === Parameters
|
199
|
+
#
|
200
|
+
# [width (Integer)] the width to scale the image to
|
201
|
+
# [height (Integer)] the height to scale the image to
|
202
|
+
# [background (String, :transparent)] the color of the background as a hexcode, like "#ff45de"
|
203
|
+
# [gravity (Magick::GravityType)] how to position the image
|
204
|
+
#
|
205
|
+
# === Yields
|
206
|
+
#
|
207
|
+
# [Magick::Image] additional manipulations to perform
|
208
|
+
#
|
209
|
+
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
|
210
|
+
manipulate! do |img|
|
211
|
+
img.resize_to_fit!(width, height)
|
212
|
+
new_img = ::Magick::Image.new(width, height)
|
213
|
+
if background == :transparent
|
214
|
+
filled = new_img.matte_floodfill(1, 1)
|
215
|
+
else
|
216
|
+
filled = new_img.color_floodfill(1, 1, ::Magick::Pixel.from_color(background))
|
217
|
+
end
|
218
|
+
destroy_image(new_img)
|
219
|
+
filled.composite!(img, gravity, ::Magick::OverCompositeOp)
|
220
|
+
destroy_image(img)
|
221
|
+
filled = yield(filled) if block_given?
|
222
|
+
filled
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
##
|
227
|
+
# Manipulate the image with RMagick. This method will load up an image
|
228
|
+
# and then pass each of its frames to the supplied block. It will then
|
229
|
+
# save the image to disk.
|
230
|
+
#
|
231
|
+
# === Gotcha
|
232
|
+
#
|
233
|
+
# This method assumes that the object responds to +current_path+.
|
234
|
+
# Any class that this module is mixed into must have a +current_path+ method.
|
235
|
+
# CarrierWave::Uploader does, so you won't need to worry about this in
|
236
|
+
# most cases.
|
237
|
+
#
|
238
|
+
# === Yields
|
239
|
+
#
|
240
|
+
# [Magick::Image] manipulations to perform
|
241
|
+
#
|
242
|
+
# === Raises
|
243
|
+
#
|
244
|
+
# [CarrierWave::ProcessingError] if manipulation failed.
|
245
|
+
#
|
246
|
+
def manipulate!(options={})
|
247
|
+
cache_stored_file! if !cached?
|
248
|
+
image = ::Magick::Image.read(current_path)
|
249
|
+
|
250
|
+
frames = if image.size > 1
|
251
|
+
list = ::Magick::ImageList.new
|
252
|
+
image.each do |frame|
|
253
|
+
list << yield( frame )
|
254
|
+
end
|
255
|
+
list
|
256
|
+
else
|
257
|
+
frame = image.first
|
258
|
+
frame = yield( frame ) if block_given?
|
259
|
+
frame
|
260
|
+
end
|
261
|
+
|
262
|
+
if options[:format]
|
263
|
+
frames.write("#{options[:format]}:#{current_path}")
|
264
|
+
else
|
265
|
+
frames.write(current_path)
|
266
|
+
end
|
267
|
+
destroy_image(frames)
|
268
|
+
rescue ::Magick::ImageMagickError => e
|
269
|
+
raise CarrierWave::ProcessingError.new("Failed to manipulate with rmagick, maybe it is not an image? Original Error: #{e}")
|
270
|
+
end
|
271
|
+
|
272
|
+
private
|
273
|
+
|
274
|
+
def destroy_image(image)
|
275
|
+
image.destroy! if image.respond_to?(:destroy!)
|
276
|
+
end
|
277
|
+
|
278
|
+
end # RMagick
|
279
|
+
end # CarrierWave
|