mini_magick 3.8.1 → 4.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +5 -5
  2. data/lib/mini_gmagick.rb +1 -0
  3. data/lib/mini_magick/configuration.rb +198 -0
  4. data/lib/mini_magick/image/info.rb +192 -0
  5. data/lib/mini_magick/image.rb +456 -341
  6. data/lib/mini_magick/shell.rb +81 -0
  7. data/lib/mini_magick/tool/animate.rb +14 -0
  8. data/lib/mini_magick/tool/compare.rb +14 -0
  9. data/lib/mini_magick/tool/composite.rb +14 -0
  10. data/lib/mini_magick/tool/conjure.rb +14 -0
  11. data/lib/mini_magick/tool/convert.rb +14 -0
  12. data/lib/mini_magick/tool/display.rb +14 -0
  13. data/lib/mini_magick/tool/identify.rb +14 -0
  14. data/lib/mini_magick/tool/import.rb +14 -0
  15. data/lib/mini_magick/tool/magick.rb +14 -0
  16. data/lib/mini_magick/tool/mogrify.rb +14 -0
  17. data/lib/mini_magick/tool/mogrify_restricted.rb +15 -0
  18. data/lib/mini_magick/tool/montage.rb +14 -0
  19. data/lib/mini_magick/tool/stream.rb +14 -0
  20. data/lib/mini_magick/tool.rb +297 -0
  21. data/lib/mini_magick/utilities.rb +23 -50
  22. data/lib/mini_magick/version.rb +5 -5
  23. data/lib/mini_magick.rb +54 -65
  24. metadata +49 -51
  25. data/lib/mini_magick/command_builder.rb +0 -94
  26. data/lib/mini_magick/errors.rb +0 -4
  27. data/spec/files/actually_a_gif.jpg +0 -0
  28. data/spec/files/animation.gif +0 -0
  29. data/spec/files/composited.jpg +0 -0
  30. data/spec/files/erroneous.jpg +0 -0
  31. data/spec/files/layers.psd +0 -0
  32. data/spec/files/leaves (spaced).tiff +0 -0
  33. data/spec/files/not_an_image.php +0 -1
  34. data/spec/files/png.png +0 -0
  35. data/spec/files/simple-minus.gif +0 -0
  36. data/spec/files/simple.gif +0 -0
  37. data/spec/files/trogdor.jpg +0 -0
  38. data/spec/files/trogdor_capitalized.JPG +0 -0
  39. data/spec/lib/mini_magick/command_builder_spec.rb +0 -153
  40. data/spec/lib/mini_magick/image_spec.rb +0 -499
  41. data/spec/lib/mini_magick_spec.rb +0 -63
  42. data/spec/spec_helper.rb +0 -29
@@ -1,499 +0,0 @@
1
- require 'spec_helper'
2
- require 'pathname'
3
- require 'tempfile'
4
-
5
- MiniMagick.processor = :mogrify
6
-
7
- describe MiniMagick::Image do
8
- context 'when ImageMagick and GraphicsMagick are both unavailable' do
9
- before do
10
- MiniMagick::Utilities.expects(:which).at_least_once.returns(nil)
11
- MiniMagick.instance_variable_set(:@processor, nil)
12
- @old_path = ENV['PATH']
13
- ENV['PATH'] = ''
14
- end
15
-
16
- after do
17
- ENV['PATH'] = @old_path
18
- end
19
-
20
- it "raises an exception with 'No such file' in the message" do
21
- begin
22
- described_class.open(SIMPLE_IMAGE_PATH)
23
- rescue => e
24
- expect(e.message).to match(/(No such file|not found)/)
25
- end
26
- end
27
- end
28
-
29
- describe 'ported from testunit', :ported => true do
30
- it 'reads image from blob' do
31
- File.open(SIMPLE_IMAGE_PATH, 'rb') do |f|
32
- image = described_class.read(f.read)
33
- expect(image).to be_valid
34
- image.destroy!
35
- end
36
- end
37
-
38
- it 'reads image from tempfile', :if => !MiniMagick::Utilities.windows? do
39
- tempfile = Tempfile.new('magick')
40
-
41
- File.open(SIMPLE_IMAGE_PATH, 'rb') do |f|
42
- tempfile.write(f.read)
43
- tempfile.rewind
44
- end
45
-
46
- image = described_class.read(tempfile)
47
- expect(image).to be_valid
48
- image.destroy!
49
- end
50
-
51
- # from https://github.com/minimagick/minimagick/issues/163
52
- it 'annotates image with whitespace' do
53
- image = described_class.open(SIMPLE_IMAGE_PATH)
54
-
55
- expect {
56
- message = 'a b'
57
-
58
- image.combine_options do |c|
59
- c.gravity 'SouthWest'
60
- c.fill 'white'
61
- c.stroke 'black'
62
- c.strokewidth '2'
63
- c.pointsize '48'
64
- c.interline_spacing '-9'
65
- c.annotate '0', message
66
- end
67
- }.to_not raise_error
68
- end
69
-
70
- it 'opens image' do
71
- image = described_class.open(SIMPLE_IMAGE_PATH)
72
- expect(image).to be_valid
73
- image.destroy!
74
- end
75
-
76
- it 'reads image from buffer' do
77
- buffer = StringIO.new File.open(SIMPLE_IMAGE_PATH, 'rb') { |f| f.read }
78
- image = described_class.read(buffer)
79
- expect(image).to be_valid
80
- image.destroy!
81
- end
82
-
83
- describe '.create' do
84
- subject(:create) do
85
- described_class.create do |f|
86
- # Had to replace the old File.read with the following to work across all platforms
87
- f.write(File.open(SIMPLE_IMAGE_PATH, 'rb') { |fi| fi.read })
88
- end
89
- end
90
-
91
- it 'creates an image' do
92
- expect {
93
- image = create
94
- image.destroy!
95
- }.to_not raise_error
96
- end
97
-
98
- describe 'validation' do
99
- before do
100
- @old_validate = MiniMagick.validate_on_create
101
- MiniMagick.validate_on_create = validate
102
- end
103
-
104
- context 'MiniMagick.validate_on_create = true' do
105
- let(:validate) { true }
106
-
107
- it 'validates image' do
108
- described_class.any_instance.expects(:valid?).returns(true)
109
- create
110
- end
111
- end
112
-
113
- context 'MiniMagick.validate_on_create = false' do
114
- let(:validate) { false }
115
-
116
- it 'skips validation' do
117
- described_class.any_instance.expects(:valid?).never
118
- create
119
- end
120
- end
121
-
122
- after { MiniMagick.validate_on_create = @old_validate }
123
- end
124
- end
125
-
126
- it 'loads a new image' do
127
- expect {
128
- image = described_class.new(SIMPLE_IMAGE_PATH)
129
- image.destroy!
130
- }.to_not raise_error
131
- end
132
-
133
- it 'loads remote image' do
134
- image = described_class.open('http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png')
135
- expect(image).to be_valid
136
- image.destroy!
137
- end
138
-
139
- it 'loads remote image with complex url' do
140
- image = described_class.open(
141
- 'http://a0.twimg.com/a/1296609216/images/fronts/logo_withbird_home.png?extra=foo&plus=bar'
142
- )
143
- expect(image).to be_valid
144
- image.destroy!
145
- end
146
-
147
- it 'reformats an image with a given extension' do
148
- expect {
149
- image = described_class.open(CAP_EXT_PATH)
150
- image.format 'jpg'
151
- }.to_not raise_error
152
- end
153
-
154
- describe '#write' do
155
- it 'reformats a PSD with a given a extension and all layers' do
156
- expect {
157
- image = described_class.open(PSD_IMAGE_PATH)
158
- image.format('jpg', nil)
159
- }.to_not raise_error
160
- end
161
-
162
- it 'opens and writes an image' do
163
- output_path = 'output.gif'
164
- begin
165
- image = described_class.new(SIMPLE_IMAGE_PATH)
166
- image.write output_path
167
- expect(File.exist?(output_path)).to be(true)
168
- ensure
169
- File.delete output_path
170
- end
171
- image.destroy!
172
- end
173
-
174
- it 'opens and writes an image with space in its filename' do
175
- output_path = 'test output.gif'
176
- begin
177
- image = described_class.new(SIMPLE_IMAGE_PATH)
178
- image.write output_path
179
-
180
- expect(File.exist?(output_path)).to be(true)
181
- ensure
182
- File.delete output_path
183
- end
184
- image.destroy!
185
- end
186
-
187
- it 'writes an image with stream' do
188
- stream = StringIO.new
189
- image = described_class.open(SIMPLE_IMAGE_PATH)
190
- image.write("#{Dir.tmpdir}/foo.gif")
191
- image.write(stream)
192
- expect(described_class.read(stream.string)).to be_valid
193
- image.destroy!
194
- end
195
-
196
- describe 'validation' do
197
- let(:image) { described_class.new(SIMPLE_IMAGE_PATH) }
198
- let(:output_path) { 'output.gif' }
199
-
200
- before do
201
- @old_validate = MiniMagick.validate_on_write
202
- MiniMagick.validate_on_write = validate
203
- end
204
-
205
- subject(:write) { image.write output_path }
206
-
207
- context 'MiniMagick.validate_on_write = true' do
208
- let(:validate) { true }
209
-
210
- it 'runs post-validation' do
211
- image.expects(:run_command).with('identify', output_path)
212
- write
213
- end
214
- end
215
-
216
- context 'MiniMagick.validate_on_write = false' do
217
- let(:validate) { false }
218
-
219
- it 'runs post-validation' do
220
- image.expects(:run_command).never
221
- write
222
- end
223
- end
224
-
225
- after do
226
- image.destroy!
227
- File.delete output_path
228
- MiniMagick.validate_on_write = @old_validate
229
- end
230
- end
231
- end
232
-
233
- it 'tells when an image is invalid' do
234
- image = described_class.new(NOT_AN_IMAGE_PATH)
235
- expect(image).not_to be_valid
236
- image.destroy!
237
- end
238
-
239
- it "raises error when opening a file that isn't an image" do
240
- expect {
241
- image = described_class.open(NOT_AN_IMAGE_PATH)
242
- image.destroy
243
- }.to raise_error(MiniMagick::Invalid)
244
- end
245
-
246
- it "raises error when imagemagick raised an error during processing" do
247
- image = described_class.open(SIMPLE_IMAGE_PATH)
248
- image.rotate "invalid_value"
249
- expect { image.run_queue }.to raise_error(MiniMagick::Error)
250
- end
251
-
252
- it 'inspects image meta info' do
253
- image = described_class.new(SIMPLE_IMAGE_PATH)
254
- expect(image[:width]).to be(150)
255
- expect(image[:height]).to be(55)
256
- expect(image[:dimensions]).to match_array [150, 55]
257
- expect(image[:colorspace]).to be_an_instance_of(String)
258
- expect(image[:format]).to match(/^gif$/i)
259
- image.destroy!
260
- end
261
-
262
- it 'supports string keys for dimension attributes' do
263
- image = described_class.new(SIMPLE_IMAGE_PATH)
264
- expect(image["width"]).to be(150)
265
- expect(image["height"]).to be(55)
266
- expect(image["dimensions"]).to match_array [150, 55]
267
- image.destroy!
268
- end
269
-
270
- it 'inspects an erroneus image meta info' do
271
- image = described_class.new(ERRONEOUS_IMAGE_PATH)
272
- expect(image[:width]).to be(10)
273
- expect(image[:height]).to be(10)
274
- expect(image[:dimensions]).to match_array [10, 10]
275
- expect(image[:format]).to eq 'JPEG'
276
- image.destroy!
277
- end
278
-
279
- it 'inspects meta info from tiff images' do
280
- image = described_class.new(TIFF_IMAGE_PATH)
281
- expect(image[:format].to_s.downcase).to eq 'tiff'
282
- expect(image[:width]).to be(50)
283
- expect(image[:height]).to be(41)
284
- image.destroy!
285
- end
286
-
287
- it 'inspects a gif with jpg format correctly' do
288
- image = described_class.new(GIF_WITH_JPG_EXT)
289
- expect(image[:format].to_s.downcase).to eq 'gif'
290
- image.destroy!
291
- end
292
-
293
- it 'resizes an image correctly' do
294
- image = described_class.open(SIMPLE_IMAGE_PATH)
295
- image.resize '20x30!'
296
-
297
- expect(image[:width]).to be(20)
298
- expect(image[:height]).to be(30)
299
- expect(image[:format]).to match(/^gif$/i)
300
- image.destroy!
301
- end
302
-
303
- it 'resizes an image with minimum dimensions' do
304
- image = described_class.open(SIMPLE_IMAGE_PATH)
305
- original_width, original_height = image[:width], image[:height]
306
- image.resize "#{original_width + 10}x#{original_height + 10}>"
307
-
308
- expect(image[:width]).to be original_width
309
- expect(image[:height]).to be original_height
310
- image.destroy!
311
- end
312
-
313
- it 'combines options to create an image with resize and blur' do
314
- image = described_class.open(SIMPLE_IMAGE_PATH)
315
- image.combine_options do |c|
316
- c.resize '20x30!'
317
- c.blur '50'
318
- end
319
-
320
- expect(image[:width]).to be(20)
321
- expect(image[:height]).to be(30)
322
- expect(image[:format]).to match(/\Agif\z/i)
323
- image.destroy!
324
- end
325
-
326
- it "combines options to create an image even with minuses symbols on it's name it" do
327
- image = described_class.open(SIMPLE_IMAGE_PATH)
328
- background = '#000000'
329
- expect {
330
- image.combine_options do |c|
331
- c.draw "image Over 0,0 10,10 '#{MINUS_IMAGE_PATH}'"
332
- c.thumbnail '300x500>'
333
- c.background background
334
- end
335
- }.to_not raise_error
336
- image.destroy!
337
- end
338
-
339
- it 'inspects the EXIF of an image' do
340
- image = described_class.open(EXIF_IMAGE_PATH)
341
- expect(image['exif:ExifVersion']).to eq '0220'
342
- image = described_class.open(SIMPLE_IMAGE_PATH)
343
- expect(image['EXIF:ExifVersion']).to be_empty
344
- image.destroy!
345
- end
346
-
347
- it 'inspects the original at of an image' do
348
- image = described_class.open(EXIF_IMAGE_PATH)
349
- expect(image[:original_at]).to eq Time.local('2005', '2', '23', '23', '17', '24')
350
- image = described_class.open(SIMPLE_IMAGE_PATH)
351
- expect(image[:original_at]).to be_nil
352
- image.destroy!
353
- end
354
-
355
- it 'has the same path for tempfile and image' do
356
- image = described_class.open(TIFF_IMAGE_PATH)
357
- expect(image.instance_eval('@tempfile.path')).to eq image.path
358
- image.destroy!
359
- end
360
-
361
- it 'has the tempfile at path after format' do
362
- image = described_class.open(TIFF_IMAGE_PATH)
363
- image.format('png')
364
- expect(File.exist?(image.path)).to be(true)
365
- image.destroy!
366
- end
367
-
368
- it "hasn't previous tempfile at path after format" do
369
- image = described_class.open(TIFF_IMAGE_PATH)
370
- before = image.path.dup
371
- image.format('png')
372
- expect(File.exist?(before)).to be(false)
373
- image.destroy!
374
- end
375
-
376
- it 'changes the format of image with special characters', :if => !MiniMagick::Utilities.windows? do
377
- tempfile = Tempfile.new('magick with special! "chars\'')
378
-
379
- File.open(SIMPLE_IMAGE_PATH, 'rb') do |file|
380
- tempfile.write(file.read)
381
- tempfile.rewind
382
- end
383
-
384
- image = described_class.new(tempfile.path)
385
- image.format('png')
386
- expect(File.exist?(image.path)).to be(true)
387
- image.destroy!
388
-
389
- File.delete(image.path)
390
- tempfile.unlink
391
- end
392
-
393
- it 'raises exception when calling wrong method' do
394
- image = described_class.open(TIFF_IMAGE_PATH)
395
- expect { image.to_blog }.to raise_error(NoMethodError)
396
- image.to_blob
397
- image.destroy!
398
- end
399
-
400
- it 'can create a composite of two images' do
401
- image = described_class.open(EXIF_IMAGE_PATH)
402
- result = image.composite(described_class.open(TIFF_IMAGE_PATH)) do |c|
403
- c.gravity 'center'
404
- end
405
- expect(File.exist?(result.path)).to be(true)
406
- end
407
-
408
- # https://github.com/minimagick/minimagick/issues/212
409
- it 'can create a composite of two images with mask' do
410
- image = described_class.open(EXIF_IMAGE_PATH)
411
- result = image.composite(described_class.open(TIFF_IMAGE_PATH), 'jpg', described_class.open(PNG_PATH)) do |c|
412
- c.gravity 'center'
413
- end
414
- expect(File.exist?(result.path)).to be(true)
415
- end
416
-
417
- # https://github.com/minimagick/minimagick/issues/8
418
- it 'has issue 8 fixed' do
419
- image = described_class.open(SIMPLE_IMAGE_PATH)
420
- expect {
421
- image.combine_options do |c|
422
- c.sample '50%'
423
- c.rotate '-90>'
424
- end
425
- }.to_not raise_error
426
- image.destroy!
427
- end
428
-
429
- # https://github.com/minimagick/minimagick/issues/8
430
- it 'has issue 15 fixed' do
431
- expect {
432
- image = described_class.open(Pathname.new(SIMPLE_IMAGE_PATH))
433
- output = Pathname.new('test.gif')
434
- image.write(output)
435
- }.to_not raise_error
436
- FileUtils.rm('test.gif')
437
- end
438
-
439
- # https://github.com/minimagick/minimagick/issues/37
440
- it 'respects the language set' do
441
- original_lang = ENV['LANG']
442
- ENV['LANG'] = 'fr_FR.UTF-8'
443
-
444
- expect {
445
- image = described_class.open(NOT_AN_IMAGE_PATH)
446
- image.destroy
447
- }.to raise_error(MiniMagick::Invalid)
448
-
449
- ENV['LANG'] = original_lang
450
- end
451
-
452
- it 'can import pixels with default format' do
453
- columns = 325
454
- rows = 200
455
- depth = 16 # 16 bits (2 bytes) per pixel
456
- map = 'gray'
457
- pixels = Array.new(columns * rows) { |i| i }
458
- blob = pixels.pack('S*') # unsigned short, native byte order
459
- image = described_class.import_pixels(blob, columns, rows, depth, map)
460
-
461
- expect(image).to be_valid
462
- expect(image[:format].to_s.downcase).to eq 'png'
463
- expect(image[:width]).to eq columns
464
- expect(image[:height]).to eq rows
465
- image.write("#{Dir.tmpdir}/imported_pixels_image.png")
466
- end
467
-
468
- it 'can import pixels with custom format' do
469
- columns = 325
470
- rows = 200
471
- depth = 16 # 16 bits (2 bytes) per pixel
472
- map = 'gray'
473
- format = 'jpeg'
474
- pixels = Array.new(columns * rows) { |i| i }
475
- blob = pixels.pack('S*') # unsigned short, native byte order
476
- image = described_class.import_pixels(blob, columns, rows, depth, map, format)
477
-
478
- expect(image).to be_valid
479
- expect(image[:format].to_s.downcase).to eq format
480
- expect(image[:width]).to eq columns
481
- expect(image[:height]).to eq rows
482
- image.write("#{Dir.tmpdir}/imported_pixels_image." + format)
483
- end
484
-
485
- it 'loads mimetype correctly' do
486
- gif = described_class.open(SIMPLE_IMAGE_PATH)
487
- jpeg = described_class.open(EXIF_IMAGE_PATH)
488
- png = described_class.open(PNG_PATH)
489
- tiff = described_class.open(TIFF_IMAGE_PATH)
490
- hidden_gif = described_class.open(GIF_WITH_JPG_EXT)
491
-
492
- expect(gif.mime_type).to eq 'image/gif'
493
- expect(jpeg.mime_type).to eq 'image/jpeg'
494
- expect(png.mime_type).to eq 'image/png'
495
- expect(tiff.mime_type).to eq 'image/tiff'
496
- expect(hidden_gif.mime_type).to eq 'image/gif'
497
- end
498
- end
499
- end
@@ -1,63 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe MiniMagick do
4
- context 'which util' do
5
- it 'identifies when mogrify exists' do
6
- expect(MiniMagick::Utilities.which('mogrify')).not_to be_nil
7
- end
8
-
9
- it 'identifies when gm exists' do
10
- expect(MiniMagick::Utilities.which('gm')).not_to be_nil
11
- end
12
-
13
- it 'returns nil on nonexistent executables' do
14
- expect(MiniMagick::Utilities.which('yogrify')).to be_nil
15
- end
16
- end
17
-
18
- context '.mogrify?' do
19
- it 'returns true if minimagick is using mogrify' do
20
- described_class.processor = :mogrify
21
- expect(described_class.mogrify?).to eq true
22
- end
23
-
24
- it 'returns false if minimagick is not using mogrify' do
25
- described_class.processor = :gm
26
- expect(described_class.mogrify?).to eq false
27
- end
28
-
29
- it 'sets the processor if not set' do
30
- described_class.processor = nil
31
- described_class.mogrify?
32
- expect(described_class.processor).to eq :mogrify
33
- end
34
- end
35
-
36
- context '.gm?' do
37
- it 'returns true if minimagick is using gm' do
38
- described_class.processor = :gm
39
- expect(described_class).to be_gm
40
- end
41
-
42
- it 'returns false if minimagick is not using gm' do
43
- described_class.processor = :mogrify
44
- expect(described_class).not_to be_gm
45
- end
46
-
47
- it 'sets the processor if not set' do
48
- described_class.processor = nil
49
- described_class.gm?
50
- expect(described_class.processor).to eq :mogrify
51
- end
52
- end
53
-
54
- context 'validation' do
55
- it 'validates on create' do
56
- expect(MiniMagick.validate_on_create).to eq(true)
57
- end
58
-
59
- it 'validates on write' do
60
- expect(MiniMagick.validate_on_write).to eq(true)
61
- end
62
- end
63
- end
data/spec/spec_helper.rb DELETED
@@ -1,29 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'rspec'
4
- require 'mocha/api'
5
-
6
- require 'mini_magick'
7
-
8
- RSpec.configure do |config|
9
- config.mock_framework = :mocha
10
- config.color = true
11
- config.formatter = 'documentation'
12
- config.raise_errors_for_deprecations!
13
- end
14
-
15
- # Image files from testunit port to RSpec
16
- test_files = File.expand_path(File.dirname(__FILE__) + '/files')
17
- TEST_FILES_PATH = test_files
18
- SIMPLE_IMAGE_PATH = test_files + '/simple.gif'
19
- MINUS_IMAGE_PATH = test_files + '/simple-minus.gif'
20
- TIFF_IMAGE_PATH = test_files + '/leaves (spaced).tiff'
21
- NOT_AN_IMAGE_PATH = test_files + '/not_an_image.php'
22
- GIF_WITH_JPG_EXT = test_files + '/actually_a_gif.jpg'
23
- EXIF_IMAGE_PATH = test_files + '/trogdor.jpg'
24
- CAP_EXT_PATH = test_files + '/trogdor_capitalized.JPG'
25
- ANIMATION_PATH = test_files + '/animation.gif'
26
- PNG_PATH = test_files + '/png.png'
27
- COMP_IMAGE_PATH = test_files + '/composited.jpg'
28
- ERRONEOUS_IMAGE_PATH = test_files + '/erroneous.jpg'
29
- PSD_IMAGE_PATH = test_files + '/layers.psd'