image_processing 0.4.5 → 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.

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