mini_magick 4.12.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20aea50f08b4b5c234dc8167e3b8f344b3bb5e279e4d28857ce38d2acbdc0772
4
- data.tar.gz: 513048f1e3315516fe592da1ecb3dec41f8e7a55e8165fe37db0720a297c5daa
3
+ metadata.gz: b2745570a5fe6e4da7ac8ab1cac8ad6799d6790893d1a1b626835f2e64f81f89
4
+ data.tar.gz: 4a3d182ac394001a77df8f137f48b8f46fd2e85d4bd60d08d5ef04c44949675d
5
5
  SHA512:
6
- metadata.gz: b5e8d72969c3649b4514a5b53fb5d228fb5db58bd9bdef0b7457838ed1289e62c8a6c0ec28cda9463fc16a159724d024a23043de5a377c2824f5bc9b148a627d
7
- data.tar.gz: 28e78716378e97ba8c57758cb684b0428d734c1e5163f626a53b38f52c8f133db7fe0f041727c3a5ee200d241cdbd9409986caacc49746d361905c76a4bfed38
6
+ metadata.gz: aaa65a8d47dd6c558d4207d0412f25bcf1ffcc79bcab07be9f6ca973bb175de9d57288a3348aa16bc85606647e499390e291878b12cdfda36ce14609ac5fb75b
7
+ data.tar.gz: '0584062e993c3330236f84a0e91ef88ca36441c92bd81a6f3de35b89feefdc53a04d93613e0e684c847c65875367321f5f8565758b6ade5d5ca6737f45922149'
data/README.md ADDED
@@ -0,0 +1,540 @@
1
+ # MiniMagick
2
+ [![Gem Version](https://img.shields.io/gem/v/mini_magick.svg)](http://rubygems.org/gems/mini_magick)
3
+ [![Gem Downloads](https://img.shields.io/gem/dt/mini_magick.svg)](http://rubygems.org/gems/mini_magick)
4
+ [![CI](https://github.com/minimagick/minimagick/actions/workflows/ci.yml/badge.svg)](https://github.com/minimagick/minimagick/actions/workflows/ci.yml)
5
+ [![Code Climate](https://codeclimate.com/github/minimagick/minimagick/badges/gpa.svg)](https://codeclimate.com/github/minimagick/minimagick)
6
+
7
+ A ruby wrapper for [ImageMagick](http://imagemagick.org/) command line.
8
+
9
+ ## Why?
10
+
11
+ I was using [RMagick](https://github.com/rmagick/rmagick) and loving it, but it
12
+ was eating up huge amounts of memory. Even a simple script would use over 100MB
13
+ of RAM. On my local machine this wasn't a problem, but on my hosting server the
14
+ ruby apps would crash because of their 100MB memory limit.
15
+
16
+ ## Solution!
17
+
18
+ Using MiniMagick the ruby processes memory remains small (it spawns
19
+ ImageMagick's command line program mogrify which takes up some memory as well,
20
+ but is much smaller compared to RMagick). See [Thinking of switching from
21
+ RMagick?](#thinking-of-switching-from-rmagick) below.
22
+
23
+ MiniMagick gives you access to all the command line options ImageMagick has
24
+ (found [here](http://www.imagemagick.org/script/command-line-options.php)).
25
+
26
+ ## Requirements
27
+
28
+ ImageMagick command-line tool has to be installed. You can check if you have it
29
+ installed by running
30
+
31
+ ```sh
32
+ $ magick -version
33
+ Version: ImageMagick 7.1.1-33 Q16-HDRI aarch64 22263 https://imagemagick.org
34
+ Copyright: (C) 1999 ImageMagick Studio LLC
35
+ License: https://imagemagick.org/script/license.php
36
+ Features: Cipher DPC HDRI Modules OpenMP(5.0)
37
+ Delegates (built-in): bzlib fontconfig freetype gslib heic jng jp2 jpeg jxl lcms lqr ltdl lzma openexr png ps raw tiff webp xml zlib zstd
38
+ Compiler: gcc (4.2)
39
+ ```
40
+
41
+ ## Installation
42
+
43
+ Add the gem to your Gemfile:
44
+
45
+ ```sh
46
+ $ bundle add mini_magick
47
+ ```
48
+
49
+ ## Information
50
+
51
+ * [API documentation](https://rubydoc.info/gems/mini_magick)
52
+
53
+ ## Usage
54
+
55
+ Let's first see a basic example of resizing an image.
56
+
57
+ ```rb
58
+ require "mini_magick"
59
+
60
+ image = MiniMagick::Image.open("input.jpg")
61
+ image.path #=> "/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/magick20140921-75881-1yho3zc.jpg"
62
+ image.resize "100x100"
63
+ image.format "png"
64
+ image.write "output.png"
65
+ ```
66
+
67
+ `MiniMagick::Image.open` makes a copy of the image, and further methods modify
68
+ that copy (the original stays untouched). We then
69
+ [resize](http://www.imagemagick.org/script/command-line-options.php#resize)
70
+ the image, and write it to a file. The writing part is necessary because
71
+ the copy is just temporary, it gets garbage collected when we lose reference
72
+ to the image.
73
+
74
+ `MiniMagick::Image.open` also accepts URLs, and options passed in will be
75
+ forwarded to [open-uri](https://github.com/ruby/open-uri).
76
+
77
+ ```rb
78
+ image = MiniMagick::Image.open("http://example.com/image.jpg")
79
+ image.contrast
80
+ image.write("from_internets.jpg")
81
+ ```
82
+
83
+ On the other hand, if we want the original image to actually *get* modified,
84
+ we can use `MiniMagick::Image.new`.
85
+
86
+ ```rb
87
+ image = MiniMagick::Image.new("input.jpg")
88
+ image.path #=> "input.jpg"
89
+ image.resize "100x100"
90
+ # Not calling #write, because it's not a copy
91
+ ```
92
+
93
+ ### Combine options
94
+
95
+ While using methods like `#resize` directly is convenient, if we use more
96
+ methods in this way, it quickly becomes inefficient, because it calls the
97
+ command on each methods call. `MiniMagick::Image#combine_options` takes
98
+ multiple options and from them builds one single command.
99
+
100
+ ```rb
101
+ image.combine_options do |b|
102
+ b.resize "250x200>"
103
+ b.rotate "-90"
104
+ b.flip
105
+ end # the command gets executed
106
+ ```
107
+
108
+ As a handy shortcut, `MiniMagick::Image.new` also accepts an optional block
109
+ which is used to `combine_options`.
110
+
111
+ ```rb
112
+ image = MiniMagick::Image.new("input.jpg") do |b|
113
+ b.resize "250x200>"
114
+ b.rotate "-90"
115
+ b.flip
116
+ end # the command gets executed
117
+ ```
118
+
119
+ The yielded builder is an instance of `MiniMagick::Tool`. To learn more
120
+ about its interface, see [Tools](#tools) below.
121
+
122
+ ### Attributes
123
+
124
+ A `MiniMagick::Image` has various handy attributes.
125
+
126
+ ```rb
127
+ image.type #=> "JPEG"
128
+ image.width #=> 250
129
+ image.height #=> 300
130
+ image.dimensions #=> [250, 300]
131
+ image.size #=> 3451 (in bytes)
132
+ image.colorspace #=> "DirectClass sRGB"
133
+ image.exif #=> {"DateTimeOriginal" => "2013:09:04 08:03:39", ...}
134
+ image.resolution #=> [75, 75]
135
+ image.signature #=> "60a7848c4ca6e36b8e2c5dea632ecdc29e9637791d2c59ebf7a54c0c6a74ef7e"
136
+ ```
137
+
138
+ If you need more control, you can also access [raw image
139
+ attributes](http://www.imagemagick.org/script/escape.php):
140
+
141
+ ```rb
142
+ image["%[gamma]"] # "0.9"
143
+ ```
144
+
145
+ To get the all information about the image, MiniMagick gives you a handy method
146
+ which returns the output from `magick input.jpg json:`:
147
+
148
+ ```rb
149
+ image.data #=>
150
+ # {
151
+ # "format": "JPEG",
152
+ # "mimeType": "image/jpeg",
153
+ # "class": "DirectClass",
154
+ # "geometry": {
155
+ # "width": 200,
156
+ # "height": 276,
157
+ # "x": 0,
158
+ # "y": 0
159
+ # },
160
+ # "resolution": {
161
+ # "x": "300",
162
+ # "y": "300"
163
+ # },
164
+ # "colorspace": "sRGB",
165
+ # "channelDepth": {
166
+ # "red": 8,
167
+ # "green": 8,
168
+ # "blue": 8
169
+ # },
170
+ # "quality": 92,
171
+ # "properties": {
172
+ # "date:create": "2016-07-11T19:17:53+08:00",
173
+ # "date:modify": "2016-07-11T19:17:53+08:00",
174
+ # "exif:ColorSpace": "1",
175
+ # "exif:ExifImageLength": "276",
176
+ # "exif:ExifImageWidth": "200",
177
+ # "exif:ExifOffset": "90",
178
+ # "exif:Orientation": "1",
179
+ # "exif:ResolutionUnit": "2",
180
+ # "exif:XResolution": "300/1",
181
+ # "exif:YResolution": "300/1",
182
+ # "icc:copyright": "Copyright (c) 1998 Hewlett-Packard Company",
183
+ # "icc:description": "sRGB IEC61966-2.1",
184
+ # "icc:manufacturer": "IEC http://www.iec.ch",
185
+ # "icc:model": "IEC 61966-2.1 Default RGB colour space - sRGB",
186
+ # "jpeg:colorspace": "2",
187
+ # "jpeg:sampling-factor": "1x1,1x1,1x1",
188
+ # "signature": "1b2336f023e5be4a9f357848df9803527afacd4987ecc18c4295a272403e52c1"
189
+ # },
190
+ # ...
191
+ # }
192
+ ```
193
+
194
+ ### Pixels
195
+
196
+ With MiniMagick you can retrieve a matrix of image pixels, where each member of
197
+ the matrix is a 3-element array of numbers between 0-255, one for each range of
198
+ the RGB color channels.
199
+
200
+ ```rb
201
+ image = MiniMagick::Image.open("image.jpg")
202
+ pixels = image.get_pixels
203
+ pixels[3][2][1] # the green channel value from the 4th-row, 3rd-column pixel
204
+ ```
205
+
206
+ It can also be called after applying transformations:
207
+
208
+ ```rb
209
+ image = MiniMagick::Image.open("image.jpg")
210
+ image.crop "20x30+10+5"
211
+ image.colorspace "Gray"
212
+ pixels = image.get_pixels
213
+ ```
214
+
215
+ ### Pixels To Image
216
+
217
+ Sometimes when you have pixels and want to create image from pixels, you can do this to form an image:
218
+
219
+ ```rb
220
+ image = MiniMagick::Image.open('/Users/rabin/input.jpg')
221
+ pixels = image.get_pixels
222
+ depth = 8
223
+ dimension = [image.width, image.height]
224
+ map = 'rgb'
225
+ image = MiniMagick::Image.get_image_from_pixels(pixels, dimension, map, depth ,'jpg')
226
+ image.write('/Users/rabin/output.jpg')
227
+ ```
228
+
229
+ In this example, the returned pixels should now have equal R, G, and B values.
230
+
231
+ ### Configuration
232
+
233
+ Here are the available configuration options with their default values:
234
+
235
+ ```rb
236
+ MiniMagick.configure do |config|
237
+ config.timeout = nil # number of seconds IM commands may take
238
+ config.errors = true # raise errors non nonzero exit status
239
+ config.warnings = true # forward warnings to standard error
240
+ config.tmdir = Dir.tmpdir # alternative directory for tempfiles
241
+ config.logger = Logger.new($stdout) # where to log IM commands
242
+ config.cli_prefix = nil # add prefix to all IM commands
243
+ end
244
+ ```
245
+
246
+ For a more information, see
247
+ [Configuration](https://rubydoc.info/gems/mini_magick/MiniMagick/Configuration) API documentation.
248
+
249
+ ### Composite
250
+
251
+ MiniMagick also allows you to
252
+ [composite](http://www.imagemagick.org/script/composite.php) images:
253
+
254
+ ```rb
255
+ first_image = MiniMagick::Image.new("first.jpg")
256
+ second_image = MiniMagick::Image.new("second.jpg")
257
+ result = first_image.composite(second_image) do |c|
258
+ c.compose "Over" # OverCompositeOp
259
+ c.geometry "+20+20" # copy second_image onto first_image from (20, 20)
260
+ end
261
+ result.write "output.jpg"
262
+ ```
263
+
264
+ ### Layers/Frames/Pages
265
+
266
+ For multilayered images you can access its layers.
267
+
268
+ ```rb
269
+ gif.frames #=> [...]
270
+ pdf.pages #=> [...]
271
+ psd.layers #=> [...]
272
+
273
+ gif.frames.each_with_index do |frame, idx|
274
+ frame.write("frame#{idx}.jpg")
275
+ end
276
+ ```
277
+
278
+ ### Image validation
279
+
280
+ You can test whether an image is valid by running it through `identify`:
281
+
282
+ ```rb
283
+ image.valid?
284
+ image.validate! # raises MiniMagick::Invalid if image is invalid
285
+ ```
286
+
287
+ ### Logging
288
+
289
+ You can choose to log MiniMagick commands and their execution times:
290
+
291
+ ```rb
292
+ MiniMagick.logger.level = Logger::DEBUG
293
+ ```
294
+ ```
295
+ D, [2016-03-19T07:31:36.755338 #87191] DEBUG -- : [0.01s] identify /var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/mini_magick20160319-87191-1ve31n1.jpg
296
+ ```
297
+
298
+ In Rails you'll probably want to set `MiniMagick.logger = Rails.logger`.
299
+
300
+ ## Tools
301
+
302
+ If you prefer not to use the `MiniMagick::Image` abstraction, you can use ImageMagick's command-line tools directly:
303
+
304
+ ```rb
305
+ MiniMagick.convert do |convert|
306
+ convert << "input.jpg"
307
+ convert.resize("100x100")
308
+ convert.negate
309
+ convert << "output.jpg"
310
+ end #=> `magick input.jpg -resize 100x100 -negate output.jpg`
311
+
312
+ # OR
313
+
314
+ convert = MiniMagick.convert
315
+ convert << "input.jpg"
316
+ convert.resize("100x100")
317
+ convert.negate
318
+ convert << "output.jpg"
319
+ convert.call #=> `magick input.jpg -resize 100x100 -negate output.jpg`
320
+ ```
321
+
322
+ This way of using MiniMagick is highly recommended if you want to maximize performance of your image processing. There are class methods for each CLI tool: `animate`, `compare`, `composite`, `conjure`, `convert`, `display`, `identify`, `import`, `mogrify` and `stream`. The `MiniMagick.convert` method will use `magick` on ImageMagick 7 and `convert` on ImageMagick 6.
323
+
324
+ ### Appending
325
+
326
+ The most basic way of building a command is appending strings:
327
+
328
+ ```rb
329
+ MiniMagick.convert do |convert|
330
+ convert << "input.jpg"
331
+ convert.merge! ["-resize", "500x500", "-negate"]
332
+ convert << "output.jpg"
333
+ end
334
+ ```
335
+
336
+ Note that it is important that every command you would pass to the command line
337
+ has to be separated with `<<`, e.g.:
338
+
339
+ ```rb
340
+ # GOOD
341
+ convert << "-resize" << "500x500"
342
+
343
+ # BAD
344
+ convert << "-resize 500x500"
345
+ ```
346
+
347
+ Shell escaping is also handled for you. If an option has a value that has
348
+ spaces inside it, just pass it as a regular string.
349
+
350
+ ```rb
351
+ convert << "-distort"
352
+ convert << "Perspective"
353
+ convert << "0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35"
354
+ ```
355
+ ```
356
+ magick -distort Perspective '0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35'
357
+ ```
358
+
359
+ ### Methods
360
+
361
+ Instead of passing in options directly, you can use Ruby methods:
362
+
363
+ ```rb
364
+ convert.resize("500x500")
365
+ convert.rotate(90)
366
+ convert.distort("Perspective", "0,0,0,0 0,45,0,45 69,0,60,10 69,45,60,35")
367
+ ```
368
+
369
+ ### Chaining
370
+
371
+ Every method call returns `self`, so you can chain them to create logical groups.
372
+
373
+ ```rb
374
+ MiniMagick.convert do |convert|
375
+ convert << "input.jpg"
376
+ convert.clone(0).background('gray').shadow('80x5+5+5')
377
+ convert.negate
378
+ convert << "output.jpg"
379
+ end
380
+ ```
381
+
382
+ ### "Plus" options
383
+
384
+ ```rb
385
+ MiniMagick.convert do |convert|
386
+ convert << "input.jpg"
387
+ convert.repage.+
388
+ convert.distort.+("Perspective", "more args")
389
+ end
390
+ ```
391
+ ```
392
+ magick input.jpg +repage +distort Perspective 'more args'
393
+ ```
394
+
395
+ ### Stacks
396
+
397
+ ```rb
398
+ MiniMagick.convert do |convert|
399
+ convert << "wand.gif"
400
+
401
+ convert.stack do |stack|
402
+ stack << "wand.gif"
403
+ stack.rotate(30)
404
+ stack.foo("bar", "baz")
405
+ end
406
+ # or
407
+ convert.stack("wand.gif", { rotate: 30, foo: ["bar", "baz"] })
408
+
409
+ convert << "images.gif"
410
+ end
411
+ ```
412
+ ```
413
+ magick wand.gif \( wand.gif -rotate 90 -foo bar baz \) images.gif
414
+ ```
415
+
416
+ ### STDIN and STDOUT
417
+
418
+ If you want to pass something to standard input, you can pass the `:stdin`
419
+ option to `#call`:
420
+
421
+ ```rb
422
+ identify = MiniMagick.identify
423
+ identify.stdin # alias for "-"
424
+ identify.call(stdin: image_content)
425
+ ```
426
+
427
+ MiniMagick also has `#stdout` alias for "-" for outputting file contents to
428
+ standard output:
429
+
430
+ ```rb
431
+ content = MiniMagick.convert do |convert|
432
+ convert << "input.jpg"
433
+ convert.auto_orient
434
+ convert.stdout # alias for "-"
435
+ end
436
+ ```
437
+
438
+ ### Capturing STDERR
439
+
440
+ Some MiniMagick tools such as `compare` output the result of the command on
441
+ standard error, even if the command succeeded. The result of
442
+ `MiniMagick::Tool#call` is always the standard output, but if you pass it a
443
+ block, it will yield the stdout, stderr and exit status of the command:
444
+
445
+ ```rb
446
+ compare = MiniMagick.compare
447
+ # build the command
448
+ compare.call do |stdout, stderr, status|
449
+ # ...
450
+ end
451
+ ```
452
+
453
+ ## Configuring
454
+
455
+ ### GraphicsMagick
456
+
457
+ As of MiniMagick 5+, [GraphicsMagick](http://www.graphicsmagick.org/) isn't
458
+ officially supported. However, you can still configure MiniMagick to use it:
459
+
460
+ ```rb
461
+ MiniMagick.configure do |config|
462
+ config.cli_prefix = "gm"
463
+ end
464
+ ```
465
+
466
+ Some MiniMagick features won't be supported, such as global timeout,
467
+ `MiniMagick::Image#data` and `MiniMagick::Image#exif`.
468
+
469
+ ### Limiting resources
470
+
471
+ ImageMagick supports a number of environment variables for controlling its
472
+ resource limits. For example, you can enforce memory or execution time limits by
473
+ setting the following variables in your application's process environment:
474
+
475
+ * `MAGICK_MEMORY_LIMIT=128MiB`
476
+ * `MAGICK_MAP_LIMIT=64MiB`
477
+ * `MAGICK_TIME_LIMIT=30`
478
+
479
+ For a full list of variables and description, see [ImageMagick's resources
480
+ documentation](http://www.imagemagick.org/script/resources.php#environment).
481
+
482
+ ### Changing temporary directory
483
+
484
+ ImageMagick allows you to change the temporary directory to process the image file:
485
+
486
+ ```rb
487
+ MiniMagick.configure do |config|
488
+ config.tmpdir = File.join(Dir.tmpdir, "/my/new/tmp_dir")
489
+ end
490
+ ```
491
+
492
+ The example directory `/my/new/tmp_dir` must exist and must be writable.
493
+
494
+ If not configured, it will default to `Dir.tmpdir`.
495
+
496
+ ### Ignoring STDERR
497
+
498
+ If you're receiving warnings from ImageMagick that you don't care about, you
499
+ can avoid them being forwarded to standard error:
500
+
501
+ ```rb
502
+ MiniMagick.configure do |config|
503
+ config.warnings = false
504
+ end
505
+ ```
506
+
507
+ ### Avoiding raising errors
508
+
509
+ This gem raises an error when ImageMagick returns a nonzero exit code.
510
+ Sometimes, however, ImageMagick returns nonzero exit codes when the command
511
+ actually went ok. In these cases, to avoid raising errors, you can add the
512
+ following configuration:
513
+
514
+ ```rb
515
+ MiniMagick.configure do |config|
516
+ config.errors = false
517
+ end
518
+ ```
519
+
520
+ You can also pass `errors: false` to individual commands:
521
+
522
+ ```rb
523
+ MiniMagick.identify(errors: false) do |b|
524
+ b.help
525
+ end
526
+ ```
527
+
528
+ ## Thinking of switching from RMagick?
529
+
530
+ Unlike RMagick, MiniMagick is a much thinner wrapper around ImageMagick.
531
+
532
+ * To piece together MiniMagick commands refer to the [Mogrify
533
+ Documentation](https://imagemagick.org/script/mogrify.php). For instance
534
+ you can use the `-flop` option as `image.flop`.
535
+ * Operations on a MiniMagick image tend to happen in-place as `image.trim`,
536
+ whereas RMagick has both copying and in-place methods like `image.trim` and
537
+ `image.trim!`.
538
+ * To open files with MiniMagick you use `MiniMagick::Image.open` as you would
539
+ `Magick::Image.read`. To open a file and directly edit it, use
540
+ `MiniMagick::Image.new`.