carrierwave-vips 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/carrierwave/vips.rb +93 -54
  3. metadata +13 -69
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65cbfca259dba6306ed6a192de3efe5efcd002c6
4
- data.tar.gz: c7fa49c3e3b663778a57bd0013b603efd9a87b87
3
+ metadata.gz: 396ab1d1691448f43668aac98834ef7632a4ef3f
4
+ data.tar.gz: 675e9ed21120941cda965f68e1409377199a8147
5
5
  SHA512:
6
- metadata.gz: 15d8611ba4a8463f8be66f7b896049035511bd5bdfd2517927358b111406ed2d8961003cdece16a68c379d29c54fbb9564caa917d287375f3371411da9bc38fd
7
- data.tar.gz: 5e3c97f22de79c6ec428c3892edf7db9eac1d457e801bdd2c66bf1ff016a647845c47c7fdfe67b506b1c880d7bb2b38aadf3f96e2d6cb4e6f29bd9eb47863c50
6
+ metadata.gz: 1bbddce513e5a8e3e306fac9076faf1b9507107fc5455a4f768f774fe04bdfc53371497fe50efe528ac9b739417d26c90ea468b157c7bd5d38406993bc9c4c1b
7
+ data.tar.gz: 1001757f7a13538405ffad122011bdad2e58df077b22f52e096e7a80fb6c2544275a53884d0b6ec4b0ea23de777b12f96d13972160885e8f4533707c7baaf5fd
@@ -9,7 +9,7 @@ module CarrierWave
9
9
  [ -1, 24, -1 ],
10
10
  [ -1, -1, -1 ]
11
11
  ]
12
- ::VIPS::Mask.new conv_mask, 16
12
+ ::Vips::Image.new_from_array conv_mask, 16
13
13
  end
14
14
 
15
15
  def self.included(base)
@@ -40,6 +40,34 @@ module CarrierWave
40
40
  def strip
41
41
  process :strip
42
42
  end
43
+
44
+ def auto_orient
45
+ process :auto_orient
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Read the camera EXIF data to determine orientation and adjust accordingly
51
+ #
52
+ def auto_orient
53
+ manipulate! do |image|
54
+ o = image.get('exif-Orientation').to_i rescue nil
55
+ o ||= image.get('exif-ifd0-Orientation').to_i rescue 1
56
+ case o
57
+ when 1
58
+ # Do nothing, everything is peachy
59
+ when 6
60
+ image.rot270
61
+ when 8
62
+ image.rot180
63
+ when 3
64
+ image.rot90
65
+ else
66
+ raise('Invalid value for Orientation: ' + o.to_s)
67
+ end
68
+ image.set('exif-Orientation', '')
69
+ image.set('exif-ifd0-Orientation', '')
70
+ end
43
71
  end
44
72
 
45
73
  ##
@@ -50,10 +78,8 @@ module CarrierWave
50
78
  # [percent (Integer)] quality from 0 to 100
51
79
  #
52
80
  def quality(percent)
53
- manipulate! do |image|
54
- @_format_opts = { :quality => percent } if jpeg? || @_format=='jpeg'
55
- image
56
- end
81
+ write_opts[:Q] = percent
82
+ get_image
57
83
  end
58
84
 
59
85
  ##
@@ -62,10 +88,8 @@ module CarrierWave
62
88
  # writing the file.
63
89
  #
64
90
  def strip
65
- manipulate! do |image|
66
- @_strip = true
67
- image
68
- end
91
+ write_opts[:strip] = true
92
+ get_image
69
93
  end
70
94
 
71
95
  ##
@@ -77,11 +101,14 @@ module CarrierWave
77
101
  # [opts (Hash)] options to be passed to converting function (ie, :interlace => true for png)
78
102
  #
79
103
  def convert(f, opts = {})
104
+ opts = opts.dup
80
105
  f = f.to_s.downcase
81
- allowed = %w(jpeg png)
106
+ allowed = %w(jpeg jpg png)
82
107
  raise ArgumentError, "Format must be one of: #{allowed.join(',')}" unless allowed.include?(f)
83
- @_format = f
84
- @_format_opts = opts
108
+ self.format_override = f == 'jpeg' ? 'jpg' : f
109
+ opts[:Q] = opts.delete(:quality) if opts.has_key?(:quality)
110
+ write_opts.merge!(opts)
111
+ get_image
85
112
  end
86
113
 
87
114
  ##
@@ -118,17 +145,22 @@ module CarrierWave
118
145
 
119
146
  image = resize_image image, new_width, new_height, :max
120
147
 
121
- if image.x_size > new_width
148
+ if image.width > new_width
122
149
  top = 0
123
- left = (image.x_size - new_width) / 2
124
- elsif image.y_size > new_height
150
+ left = (image.width - new_width) / 2
151
+ elsif image.height > new_height
125
152
  left = 0
126
- top = (image.y_size - new_height) / 2
153
+ top = (image.height - new_height) / 2
127
154
  else
128
155
  left = 0
129
156
  top = 0
130
157
  end
131
158
 
159
+ # Floating point errors can sometimes chop off an extra pixel
160
+ # TODO: fix all the universe so that floating point errors never happen again
161
+ new_height = image.height if image.height < new_height
162
+ new_width = image.width if image.width < new_width
163
+
132
164
  image.extract_area(left, top, new_width, new_height)
133
165
 
134
166
  end
@@ -147,7 +179,7 @@ module CarrierWave
147
179
  #
148
180
  def resize_to_limit(new_width, new_height)
149
181
  manipulate! do |image|
150
- image = resize_image(image,new_width,new_height) if new_width < image.x_size || new_height < image.y_size
182
+ image = resize_image(image,new_width,new_height) if new_width < image.width || new_height < image.height
151
183
  image
152
184
  end
153
185
  end
@@ -155,18 +187,18 @@ module CarrierWave
155
187
  ##
156
188
  # Manipulate the image with Vips. Saving of the image is delayed until after
157
189
  # all the process blocks have been called. Make sure you always return an
158
- # VIPS::Image object from the block
190
+ # Vips::Image object from the block
159
191
  #
160
192
  # === Gotcha
161
193
  #
162
- # This method assumes that the object responds to +current_path+.
163
- # Any class that this module is mixed into must have a +current_path+ method.
194
+ # This method assumes that the object responds to +current_path+ and +file+.
195
+ # Any class that this module is mixed into must have a +current_path+ and a +file+ method.
164
196
  # CarrierWave::Uploader does, so you won't need to worry about this in
165
197
  # most cases.
166
198
  #
167
199
  # === Yields
168
200
  #
169
- # [VIPS::Image] for further manipulation
201
+ # [Vips::Image] for further manipulation
170
202
  #
171
203
  # === Raises
172
204
  #
@@ -174,14 +206,7 @@ module CarrierWave
174
206
  #
175
207
 
176
208
  def manipulate!
177
- cache_stored_file! unless cached?
178
- @_vimage ||= if jpeg?
179
- VIPS::Image.jpeg(current_path, :sequential => true)
180
- elsif png?
181
- VIPS::Image.png(current_path, :sequential => true)
182
- else
183
- VIPS::Image.new(current_path)
184
- end
209
+ @_vimage ||= get_image
185
210
  @_vimage = yield @_vimage
186
211
  rescue => e
187
212
  raise CarrierWave::ProcessingError.new("Failed to manipulate file, maybe it is not a supported image? Original Error: #{e}")
@@ -190,59 +215,73 @@ module CarrierWave
190
215
  def process!(*)
191
216
  ret = super
192
217
  if @_vimage
193
- tmp_name = current_path.sub(/(\.[[:alnum:]]+)$/i, '_tmp\1')
194
- writer = writer_class.send(:new, @_vimage, @_format_opts)
195
- if @_strip
196
- writer.remove_exif
197
- writer.remove_icc
198
- end
199
- writer.write(tmp_name)
218
+ ext_regex = /(\.[[:alnum:]]+)$/
219
+ ext = format_override ? "_tmp.#{format_override}" : '_tmp\1'
220
+ tmp_name = current_path.sub(ext_regex, ext)
221
+ opts = write_opts.dup
222
+ opts.delete(:Q) unless write_jpeg?(tmp_name)
223
+ @_vimage.write_to_file(tmp_name, **opts)
200
224
  FileUtils.mv(tmp_name, current_path)
201
225
  @_vimage = nil
202
226
  end
203
227
  ret
204
228
  end
205
229
 
230
+ def filename
231
+ return unless original_filename
232
+ format_override ? original_filename.sub(/\.[[:alnum:]]+$/, ".#{format_override}") : original_filename
233
+ end
234
+
206
235
  private
207
236
 
208
- def writer_class
209
- case @_format
210
- when 'jpeg' then VIPS::JPEGWriter
211
- when 'png' then VIPS::PNGWriter
212
- else VIPS::Writer
213
- end
237
+ attr_accessor :format_override
238
+
239
+ def get_image
240
+ cache_stored_file! unless cached?
241
+ @_vimage ||= if jpeg? || png?
242
+ ::Vips::Image.new_from_file(current_path, access: :sequential)
243
+ else
244
+ ::Vips::Image.new_from_file(current_path)
245
+ end
246
+ end
247
+
248
+ def write_opts
249
+ @_write_opts ||= {}
214
250
  end
215
251
 
216
252
  def resize_image(image, width, height, min_or_max = :min)
217
253
  ratio = get_ratio image, width, height, min_or_max
218
254
  return image if ratio == 1
219
255
  if ratio > 1
220
- image = image.affinei_resize :nearest, ratio
256
+ image = image.resize(ratio, kernel: :nearest)
221
257
  else
222
- if ratio <= 0.5
223
- factor = (1.0 / ratio).floor
224
- image = image.shrink(factor)
225
- image = image.tile_cache(image.x_size, 1, 30)
226
- ratio = get_ratio image, width, height, min_or_max
227
- end
228
- image = image.affinei_resize :bicubic, ratio
258
+ image = image.resize(ratio, kernel: :cubic)
229
259
  image = image.conv SHARPEN_MASK
230
260
  end
231
261
  image
232
262
  end
233
263
 
234
264
  def get_ratio(image, width,height, min_or_max = :min)
235
- width_ratio = width.to_f / image.x_size
236
- height_ratio = height.to_f / image.y_size
265
+ width_ratio = width.to_f / image.width
266
+ height_ratio = height.to_f / image.height
237
267
  [width_ratio, height_ratio].send(min_or_max)
238
268
  end
239
269
 
240
270
  def jpeg?(path = current_path)
241
- path =~ /.*jpg$/i or path =~ /.*jpeg$/i
271
+ %w(jgp jpeg).include? ext(path)
242
272
  end
243
273
 
244
274
  def png?(path = current_path)
245
- path =~ /.*png$/i
275
+ ext(path) == 'png'
276
+ end
277
+
278
+ def write_jpeg?(path)
279
+ format_override == 'jpg' || jpeg?(path)
280
+ end
281
+
282
+ def ext(path)
283
+ matches = /\.([[:alnum:]]+)$/.match(path)
284
+ matches && matches[1].downcase
246
285
  end
247
286
 
248
287
  end # Vips
metadata CHANGED
@@ -1,111 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carrierwave-vips
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Nicoll
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-11 00:00:00.000000000 Z
11
+ date: 2016-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-vips
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.0
19
+ version: 1.0.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.0
26
+ version: 1.0.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: carrierwave
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rmagick
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - '>='
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: dm-core
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - '>='
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: dm-sqlite-adapter
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - '>='
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: dm-migrations
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - '>='
45
+ - - ">="
102
46
  - !ruby/object:Gem::Version
103
47
  version: '0'
104
48
  type: :development
105
49
  prerelease: false
106
50
  version_requirements: !ruby/object:Gem::Requirement
107
51
  requirements:
108
- - - '>='
52
+ - - ">="
109
53
  - !ruby/object:Gem::Version
110
54
  version: '0'
111
55
  description: Adds VIPS support to CarrierWave
@@ -125,17 +69,17 @@ require_paths:
125
69
  - lib
126
70
  required_ruby_version: !ruby/object:Gem::Requirement
127
71
  requirements:
128
- - - '>='
72
+ - - ">="
129
73
  - !ruby/object:Gem::Version
130
74
  version: '0'
131
75
  required_rubygems_version: !ruby/object:Gem::Requirement
132
76
  requirements:
133
- - - '>='
77
+ - - ">="
134
78
  - !ruby/object:Gem::Version
135
79
  version: '0'
136
80
  requirements: []
137
81
  rubyforge_project:
138
- rubygems_version: 2.0.6
82
+ rubygems_version: 2.5.1
139
83
  signing_key:
140
84
  specification_version: 4
141
85
  summary: Adds VIPS support to CarrierWave