image_processing 0.9.0 → 0.10.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 +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +45 -374
- data/lib/image_processing/chainable.rb +63 -0
- data/lib/image_processing/mini_magick/deprecated_api.rb +119 -0
- data/lib/image_processing/mini_magick.rb +67 -213
- data/lib/image_processing/pipeline.rb +59 -0
- data/lib/image_processing/version.rb +1 -1
- data/lib/image_processing/vips.rb +91 -5
- data/lib/image_processing.rb +6 -0
- metadata +5 -6
- data/lib/image_processing/vips/chainable.rb +0 -61
- data/lib/image_processing/vips/color.rb +0 -584
- data/lib/image_processing/vips/pipeline.rb +0 -30
- data/lib/image_processing/vips/processor.rb +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0907be7d4bc1b7d37149c274483394cbba923cc
|
4
|
+
data.tar.gz: 794182bb527363c95bc3f6972e74af81435bd7c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fcd9f523f50c4589b74deda0d7c41e10354faa4cdb9bfb1d26303c7246c152627b91bfcd920a59934104744a52e298f1fbcd9af63a5206219b02430c4bf3a96
|
7
|
+
data.tar.gz: 13d2d86ea9ed3940c12228a4af3adaf0073ae72be790641be8e9ad53f945902f6a0655246bb2f66a556426153a9055cb1c953a47fb70b1a14b9e9156e050c85d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
## 0.10.0 (2018-03-21)
|
2
|
+
|
3
|
+
* [minimagick] Rewrite MiniMagick module to use the chainable API (@janko-m)
|
4
|
+
|
5
|
+
* [minimagick] Deprecate the old API (@janko-m)
|
6
|
+
|
7
|
+
* [minimagick] Raise an exception on processing warnings (@janko-m)
|
8
|
+
|
9
|
+
* [minimagick] Speed up `.valid_image?` by an order of magnitude (@janko-m)
|
10
|
+
|
11
|
+
* [minimagick] Don't accept arbitrary IO object anymore (@janko-m)
|
12
|
+
|
13
|
+
* [minimagick] Removed unnecessary `#crop` and `#resample` macros (@janko-m)
|
14
|
+
|
15
|
+
* [vips] Ignore undefined loader/saver options (@janko-m)
|
16
|
+
|
17
|
+
* [vips] Preserve transparent background in `#resize_to_pad` (@janko-m)
|
18
|
+
|
19
|
+
* [vips] Remove the ability to specify colors using names (@janko-m)
|
20
|
+
|
21
|
+
* [minimagick, vips] Autorotate images after loading them (@janko-m)
|
22
|
+
|
23
|
+
* [core] Delete result `Tempfile` object in case of processing errors (@janko-m)
|
24
|
+
|
25
|
+
* [core] Allow returning `nil` in the `#custom` block (@janko-m)
|
26
|
+
|
27
|
+
* [core] Allow specifying a path string as source file (@janko-m)
|
28
|
+
|
29
|
+
* [core] Allow saving to a specific location with the `:destination` call option (@janko-m)
|
30
|
+
|
1
31
|
## 0.9.0 (2018-03-16)
|
2
32
|
|
3
33
|
* Added libvips module (@GustavoCaso, @janko-m)
|
data/README.md
CHANGED
@@ -11,46 +11,34 @@ Refile, Dragonfly and ActiveStorage each implementing their own versions.
|
|
11
11
|
## Installation
|
12
12
|
|
13
13
|
```rb
|
14
|
-
gem "image_processing"
|
14
|
+
gem "image_processing", "~> 0.10"
|
15
15
|
```
|
16
16
|
|
17
|
-
##
|
17
|
+
## Usage
|
18
18
|
|
19
|
-
|
20
|
-
[
|
19
|
+
Processing is performed through [`ImageProcessing::Vips`] or
|
20
|
+
[`ImageProcessing::MiniMagick`] modules. Both modules share the same chainable
|
21
|
+
API for defining the processing pipeline:
|
21
22
|
|
22
23
|
```rb
|
23
|
-
|
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"
|
24
|
+
require "image_processing/mini_magick"
|
37
25
|
|
38
|
-
processed = ImageProcessing::
|
26
|
+
processed = ImageProcessing::MiniMagick
|
39
27
|
.source(file)
|
40
|
-
.autorot
|
41
28
|
.resize_to_limit(400, 400)
|
42
29
|
.convert("png")
|
43
30
|
.call
|
44
31
|
|
45
|
-
processed #=> #<File:/var/folders/.../
|
32
|
+
processed #=> #<File:/var/folders/.../image_processing20180316-18446-1j247h6.png>
|
46
33
|
```
|
47
34
|
|
48
35
|
This allows easy branching when generating multiple derivatives:
|
49
36
|
|
50
37
|
```rb
|
38
|
+
require "image_processing/vips"
|
39
|
+
|
51
40
|
pipeline = ImageProcessing::Vips
|
52
41
|
.source(file)
|
53
|
-
.autorot
|
54
42
|
.convert("png")
|
55
43
|
|
56
44
|
large = pipeline.resize_to_limit!(800, 800)
|
@@ -62,14 +50,14 @@ The processing is executed on `#call` or when a processing method is called
|
|
62
50
|
with a bang (`!`).
|
63
51
|
|
64
52
|
```rb
|
65
|
-
processed = ImageProcessing::
|
53
|
+
processed = ImageProcessing::MiniMagick
|
66
54
|
.convert("png")
|
67
55
|
.resize_to_limit(400, 400)
|
68
56
|
.call(image)
|
69
57
|
|
70
58
|
# OR
|
71
59
|
|
72
|
-
processed = ImageProcessing::
|
60
|
+
processed = ImageProcessing::MiniMagick
|
73
61
|
.source(image) # declare source image
|
74
62
|
.convert("png")
|
75
63
|
.resize_to_limit(400, 400)
|
@@ -77,366 +65,64 @@ processed = ImageProcessing::Vips
|
|
77
65
|
|
78
66
|
# OR
|
79
67
|
|
80
|
-
processed = ImageProcessing::
|
68
|
+
processed = ImageProcessing::MiniMagick
|
81
69
|
.source(image)
|
82
70
|
.convert("png")
|
83
71
|
.resize_to_limit!(400, 400) # bang method
|
84
72
|
```
|
85
73
|
|
86
|
-
The source
|
87
|
-
`Vips::Image` object.
|
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.
|
74
|
+
The source object needs to responds to `#path`, or be a String, a Pathname, or
|
75
|
+
a `Vips::Image`/`MiniMagick::Tool` object.
|
224
76
|
|
225
77
|
```rb
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
File.extname(result.path)
|
231
|
-
#=> ".png"
|
78
|
+
ImageProcessing::Vips.source(File.open("source.jpg"))
|
79
|
+
ImageProcessing::Vips.source("source.jpg")
|
80
|
+
ImageProcessing::Vips.source(Pathname.new("source.jpg"))
|
81
|
+
ImageProcessing::Vips.source(Vips::Image.new_from_file("source.jpg"))
|
232
82
|
```
|
233
83
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
Sets `Vips::Image` metadata. Delegates to [`Vips::Image#set`] and
|
240
|
-
[`Vips::Image#set_type`].
|
84
|
+
Without any call options the result of processing is a newly created `Tempfile`
|
85
|
+
object. You can save processing result to a specific location by passing
|
86
|
+
`:destination` to `#call`. You can also pass `save: false` to `#call` to
|
87
|
+
retrieve the raw `Vips::Image`/`MiniMagick::Tool` object.
|
241
88
|
|
242
89
|
```rb
|
243
90
|
pipeline = ImageProcessing::Vips.source(image)
|
244
91
|
|
245
|
-
pipeline.
|
246
|
-
|
247
|
-
pipeline.
|
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)
|
92
|
+
pipeline.call #=> #<Tempfile ...>
|
93
|
+
pipeline.call(save: false) #=> #<Vips::Image ...>
|
94
|
+
pipeline.call(destination: "/path/to/destination")
|
284
95
|
```
|
285
96
|
|
286
|
-
|
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.
|
97
|
+
You can continue reading the API documentation for specific modules:
|
292
98
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
ImageProcessing::Vips
|
297
|
-
.source(vips_image)
|
298
|
-
# ...
|
299
|
-
```
|
99
|
+
* **[`ImageProcessing::Vips`]**
|
100
|
+
* **[`ImageProcessing::MiniMagick`]**
|
300
101
|
|
301
|
-
|
102
|
+
## Optimization
|
302
103
|
|
303
|
-
|
104
|
+
After images have been processed, you might want to additionally optimize them
|
105
|
+
to reduce their filesize. You can do that with the [image_optim] gem:
|
304
106
|
|
305
107
|
```rb
|
306
|
-
|
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.
|
108
|
+
require "image_optim"
|
314
109
|
|
315
|
-
|
316
|
-
false)` to get the `Vips::Image` object, and call the saver on it directly.
|
317
|
-
|
318
|
-
```rb
|
319
|
-
vips_image = ImageProcessing::Vips
|
110
|
+
result = ImageProcessing::Vips
|
320
111
|
.resize_to_limit(400, 400)
|
321
|
-
.
|
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
|
-
```
|
335
|
-
|
336
|
-
Typically you will include the module in your class:
|
337
|
-
|
338
|
-
```rb
|
339
|
-
require "image_processing/mini_magick"
|
340
|
-
|
341
|
-
include ImageProcessing::MiniMagick
|
342
|
-
|
343
|
-
original = File.open("path/to/image.jpg")
|
344
|
-
|
345
|
-
converted = convert(original, "png") # makes a converted copy
|
346
|
-
converted #=> #<File:/var/folders/.../mini_magick20151003-23030-9e1vjz.png (closed)>
|
347
|
-
File.exist?(original.path) #=> true
|
348
|
-
|
349
|
-
converted = convert!(original, "png") # converts the file in-place
|
350
|
-
converted #=> #<File:/var/folders/.../mini_magick20151003-23030-9e1vjz.png (closed)>
|
351
|
-
File.exist?(original.path) #=> false
|
352
|
-
```
|
353
|
-
|
354
|
-
You can also call processing methods directly on the module:
|
355
|
-
|
356
|
-
```rb
|
357
|
-
image = File.open("path/to/image.jpg")
|
358
|
-
|
359
|
-
ImageProcessing::MiniMagick.resize_to_fit(image, 400, 400)
|
360
|
-
```
|
361
|
-
|
362
|
-
### Methods
|
363
|
-
|
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):
|
367
|
-
|
368
|
-
```rb
|
369
|
-
# Adjust an image so that its orientation is suitable for viewing.
|
370
|
-
auto_orient[!](file)
|
371
|
-
|
372
|
-
# Converts file to the specified format, and you can specify to convert only a
|
373
|
-
# certain page for multilayered formats.
|
374
|
-
convert[!](file, format, page = nil)
|
375
|
-
|
376
|
-
# Crop image to the defined area.
|
377
|
-
crop[!](file, width, height, x_offset, y_offset, gravity: "NorthWest")
|
378
|
-
|
379
|
-
# Resizes image to fit the specified dimensions (shrinks if larger, enlarges if
|
380
|
-
# smaller, but keeps the aspect ratio).
|
381
|
-
resize_to_fit[!](file, width, height)
|
382
|
-
|
383
|
-
# Resizes image in limit of the specified dimensions (shrinks if larger, keeps
|
384
|
-
# if smaller, but keeps the aspect ratio).
|
385
|
-
resize_to_limit[!](file, width, height)
|
386
|
-
|
387
|
-
# Resizes image to fill the specified dimensions (shrinks if larger,
|
388
|
-
# enlarges if smaller, crops the longer side).
|
389
|
-
resize_to_fill[!](file, width, height, gravity: "Center")
|
390
|
-
|
391
|
-
# Resizes image to the specified dimensions and pads missing space (shrinks if
|
392
|
-
# larger, enlarges if smaller, fills the shorter side with specified color).
|
393
|
-
resize_and_pad[!](file, width, height, background: "transparent", gravity: "Center")
|
394
|
-
|
395
|
-
# Resamples the image to a different resolution
|
396
|
-
resample[!](file, horizontal, vertical)
|
397
|
-
|
398
|
-
# Returns true if the given image is corrupted
|
399
|
-
corrupted?(file)
|
400
|
-
```
|
401
|
-
|
402
|
-
The `#resize_to_limit[!]` and `#resize_to_fit[!]` allow specifying only one
|
403
|
-
dimension:
|
404
|
-
|
405
|
-
```rb
|
406
|
-
resize_to_limit(image, 300, nil)
|
407
|
-
resize_to_fit(image, nil, 500)
|
408
|
-
```
|
409
|
-
|
410
|
-
### Dropping to MiniMagick
|
411
|
-
|
412
|
-
If you want to do custom MiniMagick processing, each of the above optionally
|
413
|
-
yields an instance of `MiniMagick::Tool`, which you can use for additional
|
414
|
-
processing:
|
415
|
-
|
416
|
-
```rb
|
417
|
-
convert(file, "png") do |cmd|
|
418
|
-
cmd.background("none")
|
419
|
-
end
|
420
|
-
```
|
112
|
+
.saver(Q: 85)
|
113
|
+
.call(image)
|
421
114
|
|
422
|
-
|
423
|
-
|
115
|
+
image_optim = ImageOptim.new(...)
|
116
|
+
image_optim.optimize_image!(result.path)
|
117
|
+
result.open # refresh file descriptor
|
424
118
|
|
425
|
-
|
426
|
-
processed = with_minimagick(file) do |image|
|
427
|
-
image #=> #<MiniMagick::Image ...>
|
428
|
-
image.combine_options do |cmd|
|
429
|
-
# ...
|
430
|
-
end
|
431
|
-
end
|
432
|
-
|
433
|
-
processed #=> #<File ...>
|
119
|
+
result # optimized image
|
434
120
|
```
|
435
121
|
|
436
122
|
## Contributing
|
437
123
|
|
438
|
-
Test suite requires `imagemagick`, `graphicsmagick` and `libvips` be
|
439
|
-
On Mac OS you can install them with Homebrew:
|
124
|
+
Test suite requires `imagemagick`, `graphicsmagick` and `libvips` to be
|
125
|
+
installed. On Mac OS you can install them with Homebrew:
|
440
126
|
|
441
127
|
```
|
442
128
|
$ brew install imagemagick graphicsmagick vips
|
@@ -460,22 +146,7 @@ The `ImageProcessing::MiniMagick` functionality was extracted from
|
|
460
146
|
[ImageMagick]: https://www.imagemagick.org
|
461
147
|
[GraphicsMagick]: http://www.graphicsmagick.org
|
462
148
|
[VIPS]: http://jcupitt.github.io/libvips/
|
463
|
-
[
|
464
|
-
[
|
465
|
-
[
|
466
|
-
[libvips installation]: https://github.com/jcupitt/libvips/wiki#building-and-installing
|
149
|
+
[`ImageProcessing::Vips`]: /doc/vips.md#imageprocessingvips
|
150
|
+
[`ImageProcessing::MiniMagick`]: /doc/minimagick.md#imageprocessingminimagick
|
151
|
+
[image_optim]: https://github.com/toy/image_optim
|
467
152
|
[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
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ImageProcessing
|
2
|
+
module Chainable
|
3
|
+
def source(file)
|
4
|
+
branch default_options.merge(source: file)
|
5
|
+
end
|
6
|
+
|
7
|
+
def convert(format)
|
8
|
+
branch default_options.merge(format: format)
|
9
|
+
end
|
10
|
+
|
11
|
+
def loader(**options)
|
12
|
+
loader = default_options[:loader].merge(options)
|
13
|
+
branch default_options.merge(loader: loader)
|
14
|
+
end
|
15
|
+
|
16
|
+
def saver(**options)
|
17
|
+
saver = default_options[:saver].merge(options)
|
18
|
+
branch default_options.merge(saver: saver)
|
19
|
+
end
|
20
|
+
|
21
|
+
def operation(name, *args)
|
22
|
+
operations = default_options[:operations] + [[name, args]]
|
23
|
+
branch default_options.merge(operations: operations)
|
24
|
+
end
|
25
|
+
|
26
|
+
def custom(&block)
|
27
|
+
block ? operation(:custom, block) : self
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_missing(name, *args)
|
31
|
+
if name.to_s.end_with?("!")
|
32
|
+
send(name.to_s.chomp("!"), *args).call!
|
33
|
+
elsif name.to_s.end_with?("?")
|
34
|
+
super
|
35
|
+
else
|
36
|
+
operation(name, *args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def call(file = nil, **call_options)
|
41
|
+
options = default_options
|
42
|
+
options = options.merge(source: file) if file
|
43
|
+
|
44
|
+
branch(options).call!(**call_options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def branch(options)
|
48
|
+
options = options.merge(processor: self::Processor) if self.is_a?(Module)
|
49
|
+
Pipeline.new(options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_options
|
53
|
+
@default_options ||= {
|
54
|
+
source: nil,
|
55
|
+
loader: {},
|
56
|
+
saver: {},
|
57
|
+
format: nil,
|
58
|
+
operations: [],
|
59
|
+
processor: nil,
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|