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 +4 -4
- data/CHANGELOG.md +65 -0
- data/README.md +366 -26
- data/image_processing.gemspec +3 -2
- data/lib/image_processing.rb +1 -0
- data/lib/image_processing/mini_magick.rb +1 -1
- data/lib/image_processing/version.rb +1 -1
- data/lib/image_processing/vips.rb +13 -0
- data/lib/image_processing/vips/chainable.rb +61 -0
- data/lib/image_processing/vips/color.rb +584 -0
- data/lib/image_processing/vips/pipeline.rb +30 -0
- data/lib/image_processing/vips/processor.rb +83 -0
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8d0ca27be8b8095076a74f66c0b2c0300a83ced
|
4
|
+
data.tar.gz: a237d603ae08dc18ecafb46cb9338d3234bc0559
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
4
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
```
|
16
|
-
gem
|
17
|
-
|
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
|
-
|
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 #=> #<
|
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 #=> #<
|
350
|
+
converted #=> #<File:/var/folders/.../mini_magick20151003-23030-9e1vjz.png (closed)>
|
37
351
|
File.exist?(original.path) #=> false
|
38
352
|
```
|
39
353
|
|
40
|
-
|
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
|
52
|
-
one has both a destructive and a
|
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
|
-
|
399
|
+
corrupted?(file)
|
86
400
|
```
|
87
401
|
|
88
|
-
|
89
|
-
|
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`,
|
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
|
-
|
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
|
-
|
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
|