image_processing 0.4.5 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of image_processing might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64e87e9088659e34b81c4258d20b85b8e513a830
4
- data.tar.gz: d49790aed2ab213fbb407ae7fbfe07b61f9cfa22
3
+ metadata.gz: b8d0ca27be8b8095076a74f66c0b2c0300a83ced
4
+ data.tar.gz: a237d603ae08dc18ecafb46cb9338d3234bc0559
5
5
  SHA512:
6
- metadata.gz: 3014727fc666cf5e55cc78f1a7f34048c972173d4dad1d6f7f1a8da288c33f5103ee06c823aa3ca71d79028754f997512ed31962e7ce56e86566da50012ec7b4
7
- data.tar.gz: de09e70b7a7ae58bcf2279da17162cd77c5ce503a8a3528270a8c55b8f71459b2948dc71af313cc7d9f52017be1e99b31fccc1ed3f60e6ab12b43082ccd978a9
6
+ metadata.gz: 85d90cb3afff7bb64f6a6ab0e85bcfa0e3e5300163c72157e7c893050ebd6908c0a3224577df0bd246ea2a727dd61e5cf6c3d537971673d6f2c9449a2704b074
7
+ data.tar.gz: 94823a28788aa45e276c16894678d7137d4092c397e0d3f962ab3e46685df08eb5ea09fc7eaaa713fb380cd26bfc79449f086622e5f1a01dffc38c9c55c340fa
data/CHANGELOG.md ADDED
@@ -0,0 +1,65 @@
1
+ ## 0.9.0 (2018-03-16)
2
+
3
+ * Added libvips module (@GustavoCaso, @janko-m)
4
+
5
+ * Drop official support for MRI 2.0 and 2.1
6
+
7
+ ## 0.4.5 (2017-09-08)
8
+
9
+ * Add `lib/image_processing.rb` to allow loading via `Bundler.require` (@printercu)
10
+
11
+ ## 0.4.4 (2017-06-16)
12
+
13
+ * Fix last changes being incompatible with older Ruby versions, again (@janko-m)
14
+
15
+ ## 0.4.3 (2017-06-16)
16
+
17
+ * Fix last changes being incompatible with older Ruby versions (@janko-m)
18
+
19
+ ## 0.4.2 (2017-06-16)
20
+
21
+ * Don't use path of input file as basename for output file (@janko-m)
22
+
23
+ ## 0.4.1 (2016-09-08)
24
+
25
+ * Maintain transparent background of PNGs in `#resize_to_fill` (janko-m)
26
+
27
+ ## 0.4.0 (2016-11-07)
28
+
29
+ * Add `#corrupted?` for checking whether an image is corrupted (janko-m)
30
+
31
+ ## 0.3.0 (2016-05-03)
32
+
33
+ * Add cropping functionality to `ImageProcessing::MiniMagick` (paulgoetze)
34
+
35
+ ## 0.2.5 (2016-03-24)
36
+
37
+ * Rewind the file after making a copy in non-destructive methods (janko-m)
38
+
39
+ * Add ability to supply page number to `#convert` (janko-m)
40
+
41
+ ## 0.2.4 (2015-10-21)
42
+
43
+ * Don't error when checking MiniMagick version for older versions of MiniMagick (janko-m)
44
+
45
+ ## 0.2.3 (2015-10-17)
46
+
47
+ * Fix uploading tempfiles to S3 using aws-sdk (janko-m)
48
+
49
+ * Make nondestructive methods available on class methods on `ImageProcessing::MiniMagick` (janko-m)
50
+
51
+ ## 0.2.2 (2015-10-04)
52
+
53
+ * Make `ImageProcessing::MiniMagick#with_minimagick` public (janko-m)
54
+
55
+ * Add `ImageProcessing::MiniMagick#auto_orient` (janko-m)
56
+
57
+ ## 0.2.1 (2015-10-03)
58
+
59
+ * Include the actual code in the gem (janko-m)
60
+
61
+ ## 0.2.0 (2015-10-03)
62
+
63
+ * Add `ImageProcessing::MiniMagick#resample` for changing resolution (janko-m)
64
+
65
+ * Fix padding in `ImageProcessing::MiniMagick#resize_and_pad` (janko-m)
data/README.md CHANGED
@@ -1,23 +1,337 @@
1
1
  # ImageProcessing
2
2
 
3
- Provides higher-level helper methods for image processing in Ruby using
4
- ImageMagick.
3
+ Provides higher-level image processing functionality that is commonly needed
4
+ when accepting user uploads. Supports processing with [VIPS] and
5
+ [ImageMagick]/[GraphicsMagick].
5
6
 
6
- These methods were extracted from [refile-mini_magick], and were made generic so
7
- that they can be used in any project. The goal of image_processing is to have a
8
- centralized place where helper methods for image processing are maintained,
9
- instead of CarrierWave, Dragonfly and Refile each implementing their own.
10
-
11
- It's been tested with MRI 2.x and JRuby.
7
+ The goal of this project is to have a single place where common image
8
+ processing helper methods are maintained, instead of Paperclip, CarrierWave,
9
+ Refile, Dragonfly and ActiveStorage each implementing their own versions.
12
10
 
13
11
  ## Installation
14
12
 
15
- ```ruby
16
- gem 'image_processing'
17
- gem 'mini_magick', '>= 4.3.5'
13
+ ```rb
14
+ gem "image_processing"
15
+ ```
16
+
17
+ ## ruby-vips
18
+
19
+ The `ImageProcessing::Vips` module contains processing macros that use the
20
+ [ruby-vips] gem, which you need to install:
21
+
22
+ ```rb
23
+ # Gemfile
24
+ gem "ruby-vips", "~> 2.0"
25
+ ```
26
+
27
+ Note that you'll need to have [libvips] 8.6 or higher installed; see
28
+ the [installation instructions][libvips installation] for more details.
29
+
30
+ ### Usage
31
+
32
+ `ImageProcessing::Vips` lets you define the processing pipeline using a
33
+ chainable API:
34
+
35
+ ```rb
36
+ require "image_processing/vips"
37
+
38
+ processed = ImageProcessing::Vips
39
+ .source(file)
40
+ .autorot
41
+ .resize_to_limit(400, 400)
42
+ .convert("png")
43
+ .call
44
+
45
+ processed #=> #<File:/var/folders/.../image_processing-vips20180316-18446-1j247h6.png>
46
+ ```
47
+
48
+ This allows easy branching when generating multiple derivatives:
49
+
50
+ ```rb
51
+ pipeline = ImageProcessing::Vips
52
+ .source(file)
53
+ .autorot
54
+ .convert("png")
55
+
56
+ large = pipeline.resize_to_limit!(800, 800)
57
+ medium = pipeline.resize_to_limit!(500, 500)
58
+ small = pipeline.resize_to_limit!(300, 300)
59
+ ```
60
+
61
+ The processing is executed on `#call` or when a processing method is called
62
+ with a bang (`!`).
63
+
64
+ ```rb
65
+ processed = ImageProcessing::Vips
66
+ .convert("png")
67
+ .resize_to_limit(400, 400)
68
+ .call(image)
69
+
70
+ # OR
71
+
72
+ processed = ImageProcessing::Vips
73
+ .source(image) # declare source image
74
+ .convert("png")
75
+ .resize_to_limit(400, 400)
76
+ .call
77
+
78
+ # OR
79
+
80
+ processed = ImageProcessing::Vips
81
+ .source(image)
82
+ .convert("png")
83
+ .resize_to_limit!(400, 400) # bang method
18
84
  ```
19
85
 
20
- ## Usage
86
+ The source image needs to be an object that responds to `#path` or a
87
+ `Vips::Image` object. The result is a `Tempfile` object, or a `Vips::Image`
88
+ object if `save: false` is passed in.
89
+
90
+ ```rb
91
+ pipeline = ImageProcessing::Vips.source(image)
92
+
93
+ tempfile = pipeline.call
94
+ tempfile #=> #<Tempfile ...>
95
+
96
+ vips_image = pipeline.call(save: false)
97
+ vips_image #=> #<Vips::Image ...>
98
+ ```
99
+
100
+ #### `#resize_to_limit`
101
+
102
+ Downsizes the image to fit within the specified dimensions while retaining the
103
+ original aspect ratio. Will only resize the image if it's larger than the
104
+ specified dimensions.
105
+
106
+ ```rb
107
+ pipeline = ImageProcessing::Vips.source(image) # 600x800
108
+
109
+ result = pipeline.resize_to_limit!(400, 400)
110
+
111
+ Vips::Image.new_from_file(result.path).size
112
+ #=> [300, 400]
113
+ ```
114
+
115
+ It's possible to omit one dimension, in which case the image will be resized
116
+ only by the provided dimension.
117
+
118
+ ```rb
119
+ pipeline.resize_to_limit!(400, nil)
120
+ # or
121
+ pipeline.resize_to_limit!(nil, 400)
122
+ ```
123
+
124
+ Any additional options are forwarded to [`Vips::Image#thumbnail_image`]:
125
+
126
+ ```rb
127
+ pipeline.resize_to_limit!(400, 400, linear: true)
128
+ ```
129
+
130
+ See [`vips_thumbnail()`] for more details.
131
+
132
+ #### `#resize_to_fit`
133
+
134
+ Resizes the image to fit within the specified dimensions while retaining the
135
+ original aspect ratio. Will downsize the image if it's larger than the
136
+ specified dimensions or upsize if it's smaller.
137
+
138
+ ```rb
139
+ pipeline = ImageProcessing::Vips.source(image) # 600x800
140
+
141
+ result = pipeline.resize_to_fit!(400, 400)
142
+
143
+ Vips::Image.new_from_file(result.path).size
144
+ #=> [300, 400]
145
+ ```
146
+
147
+ It's possible to omit one dimension, in which case the image will be resized
148
+ only by the provided dimension.
149
+
150
+ ```rb
151
+ pipeline.resize_to_fit!(400, nil)
152
+ # or
153
+ pipeline.resize_to_fit!(nil, 400)
154
+ ```
155
+
156
+ Any additional options are forwarded to [`Vips::Image#thumbnail_image`]:
157
+
158
+ ```rb
159
+ pipeline.resize_to_fit!(400, 400, linear: true)
160
+ ```
161
+
162
+ See [`vips_thumbnail()`] for more details.
163
+
164
+ #### `#resize_to_fill`
165
+
166
+ Resizes the image to fill the specified dimensions while retaining the original
167
+ aspect ratio. If necessary, will crop the image in the larger dimension.
168
+
169
+ ```rb
170
+ pipeline = ImageProcessing::Vips.source(image) # 600x800
171
+
172
+ result = pipeline.resize_to_fill!(400, 400)
173
+
174
+ Vips::Image.new_from_file(result.path).size
175
+ #=> [400, 400]
176
+ ```
177
+
178
+ Any additional options are forwarded to [`Vips::Image#thumbnail_image`]:
179
+
180
+ ```rb
181
+ pipeline.resize_to_fill!(400, 400, crop: :attention) # smart crop
182
+ ```
183
+
184
+ See [`vips_thumbnail()`] for more details.
185
+
186
+ #### `#resize_and_pad`
187
+
188
+ Resizes the image to fit within the specified dimensions while retaining the
189
+ original aspect ratio. If necessary, will pad the remaining area with the given
190
+ color, which defaults to transparent (for GIF and PNG, white for JPEG).
191
+
192
+ ```rb
193
+ pipeline = ImageProcessing::Vips.source(image) # 600x800
194
+
195
+ result = pipeline.resize_and_pad!(400, 400)
196
+
197
+ Vips::Image.new_from_file(result.path).size
198
+ #=> [400, 400]
199
+ ```
200
+
201
+ You can specify the background [color] that will be used for padding:
202
+
203
+ ```rb
204
+ pipeline.resize_and_pad!(400, 400, color: "RoyalBlue")
205
+ ```
206
+
207
+ You can also specify the [direction] where the source image will be positioned:
208
+
209
+ ```rb
210
+ pipeline.resize_and_pad!(400, 400, gravity: "north-west")
211
+ ```
212
+
213
+ Any additional options are forwarded to [`Vips::Image#thumbnail_image`]:
214
+
215
+ ```rb
216
+ pipeline.resize_to_fill!(400, 400, linear: true)
217
+ ```
218
+
219
+ See [`vips_thumbnail()`] and [`vips_gravity()`] for more details.
220
+
221
+ #### `#convert`
222
+
223
+ Specifies the output format.
224
+
225
+ ```rb
226
+ pipeline = ImageProcessing::Vips.source(image)
227
+
228
+ result = pipeline.convert!("png")
229
+
230
+ File.extname(result.path)
231
+ #=> ".png"
232
+ ```
233
+
234
+ By default the original format is retained when writing the image to a file. If
235
+ the source file doesn't have a file extension, the format will default to JPEG.
236
+
237
+ #### `#set`, `#set_type`
238
+
239
+ Sets `Vips::Image` metadata. Delegates to [`Vips::Image#set`] and
240
+ [`Vips::Image#set_type`].
241
+
242
+ ```rb
243
+ pipeline = ImageProcessing::Vips.source(image)
244
+
245
+ pipeline.set("icc-profile-data", profile).call
246
+ # or
247
+ pipeline.set_type(Vips::BLOB_TYPE, "icc-profile-data", profile).call
248
+ ```
249
+
250
+ #### `#method_missing`
251
+
252
+ Any unknown methods will be delegated to [`Vips::Image`].
253
+
254
+ ```rb
255
+ ImageProcessing::Vips
256
+ .crop(0, 0, 300, 300)
257
+ .invert
258
+ .gaussblur(2)
259
+ # ...
260
+ ```
261
+
262
+ #### `#custom`
263
+
264
+ Calls the provided block with the intermediary `Vips::Image` object. The return
265
+ value of the provided block must be a `Vips::Image` object.
266
+
267
+ ```rb
268
+ ImageProcessing::Vips
269
+ .source(file)
270
+ .resize_to_limit(400, 400)
271
+ .custom { |image| image + image.invert }
272
+ .call
273
+ ```
274
+
275
+ #### `#loader`
276
+
277
+ Specifies options that will be forwarded to [`Vips::Image.new_from_file`].
278
+
279
+ ```rb
280
+ ImageProcessing::Vips
281
+ .loader(access: :sequential)
282
+ .resize_to_limit(400, 400)
283
+ .call(source)
284
+ ```
285
+
286
+ See [`vips_jpegload()`], [`vips_pngload()`] etc. for more details on
287
+ format-specific load options.
288
+
289
+ If you would like to have more control over loading, you can load the image
290
+ directly using `Vips::Image`, and just pass the `Vips::Image` object as the
291
+ source file.
292
+
293
+ ```rb
294
+ vips_image = Vips::Image.magickload(file.path, n: -1)
295
+
296
+ ImageProcessing::Vips
297
+ .source(vips_image)
298
+ # ...
299
+ ```
300
+
301
+ #### `#saver`
302
+
303
+ Specifies options that will be forwarded to [`Vips::Image#write_to_file`].
304
+
305
+ ```rb
306
+ ImageProcessing::Vips
307
+ .saver(Q: 100)
308
+ .resize_to_limit(400, 400)
309
+ .call(source)
310
+ ```
311
+
312
+ See [`vips_jpegsave()`], [`vips_pngsave()`] etc. for more details on
313
+ format-specific save options.
314
+
315
+ If you would like to have more control over saving, you can call `#call(save:
316
+ false)` to get the `Vips::Image` object, and call the saver on it directly.
317
+
318
+ ```rb
319
+ vips_image = ImageProcessing::Vips
320
+ .resize_to_limit(400, 400)
321
+ .call(save: false)
322
+
323
+ vips_image.write_to_file("/path/to/destination", **options)
324
+ ```
325
+
326
+ ## MiniMagick
327
+
328
+ The `ImageProcessing::MiniMagick` module contains processing methods that use
329
+ the [MiniMagick] gem, which you need to install:
330
+
331
+ ```rb
332
+ # Gemfile
333
+ gem "mini_magick", ">= 4.3.5"
334
+ ```
21
335
 
22
336
  Typically you will include the module in your class:
23
337
 
@@ -29,16 +343,15 @@ include ImageProcessing::MiniMagick
29
343
  original = File.open("path/to/image.jpg")
30
344
 
31
345
  converted = convert(original, "png") # makes a converted copy
32
- converted #=> #<Tempfile:/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/mini_magick20151003-23030-9e1vjz.png (closed)>
346
+ converted #=> #<File:/var/folders/.../mini_magick20151003-23030-9e1vjz.png (closed)>
33
347
  File.exist?(original.path) #=> true
34
348
 
35
349
  converted = convert!(original, "png") # converts the file in-place
36
- converted #=> #<Tempfile:/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/mini_magick20151003-23030-9e1vjz.png (closed)>
350
+ converted #=> #<File:/var/folders/.../mini_magick20151003-23030-9e1vjz.png (closed)>
37
351
  File.exist?(original.path) #=> false
38
352
  ```
39
353
 
40
- If you would rather not pollute your namespace, you can also call the methods
41
- directly on the module:
354
+ You can also call processing methods directly on the module:
42
355
 
43
356
  ```rb
44
357
  image = File.open("path/to/image.jpg")
@@ -48,8 +361,9 @@ ImageProcessing::MiniMagick.resize_to_fit(image, 400, 400)
48
361
 
49
362
  ### Methods
50
363
 
51
- The following is the list of helper methods that ImageProcessing provides (each
52
- one has both a destructive and a nondestructive version):
364
+ The following is the list of processing methods provided by
365
+ `ImageProcessing::MiniMagick` (each one has both a destructive and a
366
+ nondestructive version):
53
367
 
54
368
  ```rb
55
369
  # Adjust an image so that its orientation is suitable for viewing.
@@ -82,11 +396,11 @@ resize_and_pad[!](file, width, height, background: "transparent", gravity: "Cent
82
396
  resample[!](file, horizontal, vertical)
83
397
 
84
398
  # Returns true if the given image is corrupted
85
- currupted?(file)
399
+ corrupted?(file)
86
400
  ```
87
401
 
88
- For `#resize_to_limit[!]` and `#resize_to_fit[!]` you can don't have to specify
89
- both dimensions:
402
+ The `#resize_to_limit[!]` and `#resize_to_fit[!]` allow specifying only one
403
+ dimension:
90
404
 
91
405
  ```rb
92
406
  resize_to_limit(image, 300, nil)
@@ -96,7 +410,7 @@ resize_to_fit(image, nil, 500)
96
410
  ### Dropping to MiniMagick
97
411
 
98
412
  If you want to do custom MiniMagick processing, each of the above optionally
99
- yields an instance of `MiniMagick::Tool`, so you can use it for additional
413
+ yields an instance of `MiniMagick::Tool`, which you can use for additional
100
414
  processing:
101
415
 
102
416
  ```rb
@@ -121,21 +435,47 @@ processed #=> #<File ...>
121
435
 
122
436
  ## Contributing
123
437
 
124
- ImageMagick and GraphicsMagick are both required to be installed, on Mac this is
438
+ Test suite requires `imagemagick`, `graphicsmagick` and `libvips` be installed.
439
+ On Mac OS you can install them with Homebrew:
125
440
 
126
441
  ```
127
- $ brew install imagemagick
128
- $ brew install graphicsmagick
442
+ $ brew install imagemagick graphicsmagick vips
129
443
  ```
130
444
 
131
- Run tests with
445
+ Afterwards you can run tests with
132
446
 
133
447
  ```
134
448
  $ rake test
135
449
  ```
136
450
 
451
+ ## Credits
452
+
453
+ The `ImageProcessing::MiniMagick` functionality was extracted from
454
+ [refile-mini_magick].
455
+
137
456
  ## License
138
457
 
139
458
  [MIT](LICENSE.txt)
140
459
 
460
+ [ImageMagick]: https://www.imagemagick.org
461
+ [GraphicsMagick]: http://www.graphicsmagick.org
462
+ [VIPS]: http://jcupitt.github.io/libvips/
463
+ [MiniMagick]: https://github.com/minimagick/minimagick
464
+ [ruby-vips]: https://github.com/jcupitt/ruby-vips
465
+ [libvips]: https://github.com/jcupitt/libvips
466
+ [libvips installation]: https://github.com/jcupitt/libvips/wiki#building-and-installing
141
467
  [refile-mini_magick]: https://github.com/refile/refile-mini_magick
468
+ [`Vips::Image`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image
469
+ [`Vips::Image.new_from_file`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image#new_from_file-class_method
470
+ [`Vips::Image#write_to_file`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image#write_to_file-instance_method
471
+ [`Vips::Image#thumbnail_image`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image#thumbnail_image-instance_method
472
+ [`Vips::Image#set`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image#set-instance_method
473
+ [`Vips::Image#set_type`]: http://www.rubydoc.info/gems/ruby-vips/Vips/Image#set_type-instance_method
474
+ [`vips_thumbnail()`]: https://jcupitt.github.io/libvips/API/current/libvips-resample.html#vips-thumbnail
475
+ [`vips_gravity()`]: http://jcupitt.github.io/libvips/API/current/libvips-conversion.html#vips-gravity
476
+ [`vips_jpegload()`]: https://jcupitt.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegload
477
+ [`vips_pngload()`]: https://jcupitt.github.io/libvips/API/current/VipsForeignSave.html#vips-pngload
478
+ [`vips_jpegsave()`]: https://jcupitt.github.io/libvips/API/current/VipsForeignSave.html#vips-jpegsave
479
+ [`vips_pngsave()`]: https://jcupitt.github.io/libvips/API/current/VipsForeignSave.html#vips-pngsave
480
+ [color]: https://www.imagemagick.org/script/color.php#color_names
481
+ [direction]: http://jcupitt.github.io/libvips/API/current/libvips-conversion.html#VipsCompassDirection