carrierwave-vips 0.9.0

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.
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+
5
+ end
6
+
7
+ require 'vips'
8
+ require 'carrierwave/vips'
9
+
@@ -0,0 +1,230 @@
1
+ # encoding: utf-8
2
+
3
+ module CarrierWave
4
+ module Vips
5
+
6
+ SHARPEN_MASK = begin
7
+ conv_mask = [
8
+ [ -1, -1, -1 ],
9
+ [ -1, 16, -1 ],
10
+ [ -1, -1, -1 ]
11
+ ]
12
+ ::VIPS::Mask.new conv_mask, 8
13
+ end
14
+
15
+ def self.included(base)
16
+ base.send(:extend, ClassMethods)
17
+ end
18
+
19
+ module ClassMethods
20
+ def resize_to_limit(width, height)
21
+ process :resize_to_limit => [width, height]
22
+ end
23
+
24
+ def resize_to_fit(width, height)
25
+ process :resize_to_fit => [width, height]
26
+ end
27
+
28
+ def resize_to_fill(width, height)
29
+ process :resize_to_fill => [width, height]
30
+ end
31
+
32
+ def quality(percent)
33
+ process :quality => percent
34
+ end
35
+
36
+ def convert(extension)
37
+ process :convert => extension
38
+ end
39
+ end
40
+
41
+ ##
42
+ # Change quality of the image (if supported by file format)
43
+ #
44
+ #
45
+ # === Parameters
46
+ # [percent (Integer)] quality from 0 to 100
47
+ #
48
+ def quality(percent)
49
+ manipulate! do |image|
50
+ image.quality = percent if image.respond_to?(:quality=)
51
+ image
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Convert the file to a different format
57
+ #
58
+ #
59
+ # === Parameters
60
+ # [f (String)] the format for the file format (jpeg, png, gif)
61
+ # [opts (Hash)] options to be passed to converting function (ie, :interlace => true for png)
62
+ #
63
+ def convert(f, opts = {})
64
+ f = f.to_s.downcase
65
+ allowed = %w(jpeg png gif)
66
+ raise ArgumentError, "Format must be one of: #{allowed.join(',')}" unless allowed.include?(f)
67
+ @_format = f
68
+ @_format_opts = opts
69
+ end
70
+
71
+ ##
72
+ # Resize the image to fit within the specified dimensions while retaining
73
+ # the original aspect ratio. The image may be shorter or narrower than
74
+ # specified in the smaller dimension but will not be larger than the
75
+ # specified values.
76
+ #
77
+ #
78
+ # === Parameters
79
+ #
80
+ # [width (Integer)] the width to scale the image to
81
+ # [height (Integer)] the height to scale the image to
82
+ #
83
+ def resize_to_fit(new_width, new_height)
84
+ manipulate! do |image|
85
+ resize_image(image,new_width,new_height)
86
+ end
87
+ end
88
+
89
+ ##
90
+ # Resize the image to fit within the specified dimensions while retaining
91
+ # the aspect ratio of the original image. If necessary, crop the image in
92
+ # the larger dimension.
93
+ #
94
+ #
95
+ # === Parameters
96
+ #
97
+ # [width (Integer)] the width to scale the image to
98
+ # [height (Integer)] the height to scale the image to
99
+ #
100
+ def resize_to_fill(new_width, new_height)
101
+ manipulate! do |image|
102
+
103
+ image = resize_image image, new_width, new_height, :max
104
+
105
+ if image.x_size > new_width
106
+ top = 0
107
+ left = (image.x_size - new_width) / 2
108
+ elsif image.y_size > new_height
109
+ left = 0
110
+ top = (image.y_size - new_height) / 2
111
+ end
112
+
113
+ image.extract_area(left, top, new_width, new_height)
114
+
115
+ end
116
+ end
117
+
118
+ ##
119
+ # Resize the image to fit within the specified dimensions while retaining
120
+ # the original aspect ratio. Will only resize the image if it is larger than the
121
+ # specified dimensions. The resulting image may be shorter or narrower than specified
122
+ # in the smaller dimension but will not be larger than the specified values.
123
+ #
124
+ # === Parameters
125
+ #
126
+ # [width (Integer)] the width to scale the image to
127
+ # [height (Integer)] the height to scale the image to
128
+ #
129
+ def resize_to_limit(new_width, new_height)
130
+ manipulate! do |image|
131
+ image = resize_image(image,new_width,new_height) if new_width < image.x_size || new_height < image.y_size
132
+ image
133
+ end
134
+ end
135
+
136
+ ##
137
+ # Manipulate the image with Vips. Saving of the image is delayed until after
138
+ # all the process blocks have been called. Make sure you always return an
139
+ # VIPS::Image object from the block
140
+ #
141
+ # === Gotcha
142
+ #
143
+ # This method assumes that the object responds to +current_path+.
144
+ # Any class that this module is mixed into must have a +current_path+ method.
145
+ # CarrierWave::Uploader does, so you won't need to worry about this in
146
+ # most cases.
147
+ #
148
+ # === Yields
149
+ #
150
+ # [VIPS::Image] for further manipulation
151
+ #
152
+ # === Raises
153
+ #
154
+ # [CarrierWave::ProcessingError] if manipulation failed.
155
+ #
156
+
157
+ def manipulate!
158
+ cache_stored_file! if !cached?
159
+ @_vimage ||= VIPS::Image.new(current_path)
160
+ @_vimage = yield @_vimage
161
+ rescue => e
162
+ raise CarrierWave::ProcessingError.new("Failed to manipulate file, maybe it is not an image? Original Error: #{e}")
163
+ end
164
+
165
+ def process!(*)
166
+ ret = super
167
+ if @_vimage
168
+ tmp_name = current_path.sub(/(\.[a-z]+)$/i, '_tmp\1')
169
+ if @_format
170
+ @vimage.send(format, tmp_name, @_format_opts)
171
+ else
172
+ @_vimage.write(tmp_name)
173
+ end
174
+ FileUtils.mv(tmp_name, current_path)
175
+ @_vimage = nil
176
+ @_format = nil
177
+ end
178
+ ret
179
+ end
180
+
181
+ private
182
+
183
+ def resize_image(image, width, height, min_or_max = :min)
184
+
185
+ ratio = get_ratio image, width, height, min_or_max
186
+
187
+ if jpeg? # find the shrink ratio for loading
188
+ shrink_factors = [8,4,2,1]
189
+ shrink_factor = nil
190
+ shrink_factors.each { |sf| shrink_factor = sf if ratio < 1.0 / sf }
191
+ shrink_factor ||= shrink_factors[-1]
192
+ image = VIPS::Image.jpeg current_path, shrink_factor: shrink_factor, sequential: true
193
+ ratio = get_ratio image, width, height, min_or_max
194
+ elsif png?
195
+ image = VIPS::Image.png curren_path, :sequential => true
196
+ end
197
+
198
+ if ratio > 1
199
+ image = image.affinei_resize :nearest, ratio
200
+ elsif ratio < 1
201
+ if ratio <= 0.5
202
+ image = image.shrink((1/ratio).floor)
203
+ ratio = get_ratio image, width, height, min_or_max
204
+ end
205
+ image = image.affinei_resize :bilinear, ratio unless ratio == 1
206
+ image = image.tile_cache(image.x_size, 1, 30)
207
+ image = image.conv SHARPEN_MASK
208
+ end
209
+
210
+ image
211
+
212
+ end
213
+
214
+ def get_ratio(image, width,height, min_or_max = :min)
215
+ width_ratio = width.to_f / image.x_size
216
+ height_ratio = height.to_f / image.y_size
217
+ [width_ratio, height_ratio].send(min_or_max)
218
+ end
219
+
220
+ def jpeg?(path = current_path)
221
+ path =~ /.*jpg$/i or path =~ /.*jpeg$/i
222
+ end
223
+
224
+ def png?(path = current_path)
225
+ path =~ /.*png$/i
226
+ end
227
+
228
+
229
+ end # Vips
230
+ end # CarrierWave
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carrierwave-vips
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jeremy Nicoll
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-04 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Adds VIPS support to CarrierWave
15
+ email: eltiare@github.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/carrierwave-vips.rb
21
+ - lib/carrierwave/vips.rb
22
+ homepage: http://rubygems.org/gems/carrierwave-vips
23
+ licenses: []
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.24
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: Adds VIPS support to CarrierWave
46
+ test_files: []