mini_magick 3.8.0 → 3.8.1

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 mini_magick might be problematic. Click here for more details.

@@ -1,4 +1,6 @@
1
1
  require 'rbconfig'
2
+ require 'shellwords'
3
+ require 'pathname'
2
4
 
3
5
  module MiniMagick
4
6
  module Utilities
@@ -22,6 +24,18 @@ module MiniMagick
22
24
  RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
23
25
  end
24
26
 
27
+ def escape(value)
28
+ if windows?
29
+ windows_escape(value)
30
+ else
31
+ shell_escape(value)
32
+ end
33
+ end
34
+
35
+ def shell_escape(value)
36
+ Shellwords.escape(value)
37
+ end
38
+
25
39
  def windows_escape(value)
26
40
  # For Windows, ^ is the escape char, equivalent to \ in Unix.
27
41
  escaped = value.gsub(/\^/, '^^').gsub(/>/, '^>')
@@ -31,6 +45,18 @@ module MiniMagick
31
45
  escaped
32
46
  end
33
47
  end
48
+
49
+ def path(path)
50
+ if windows?
51
+ # For Windows, if a path contains space char, you need to quote it,
52
+ # otherwise you SHOULD NOT quote it. If you quote a path that does
53
+ # not contains space, it will not work.
54
+ pathname = Pathname.new(path).to_s
55
+ path.include?(' ') ? pathname.inspect : pathname
56
+ else
57
+ path
58
+ end
59
+ end
34
60
  end
35
61
  end
36
62
  end
@@ -1,3 +1,17 @@
1
1
  module MiniMagick
2
- VERSION = '3.8.0'
2
+ ##
3
+ # Returns the version of the currently loaded MiniMagick as
4
+ # a <tt>Gem::Version</tt>.
5
+ def self.version
6
+ Gem::Version.new VERSION::STRING
7
+ end
8
+
9
+ module VERSION
10
+ MAJOR = 3
11
+ MINOR = 8
12
+ TINY = 1
13
+ PRE = nil
14
+
15
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
16
+ end
3
17
  end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <?php I am so not an image ?>
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ # All tests tagged as `ported` are ported from
4
+ # testunit tests and are there for backwards compatibility
5
+
6
+ MiniMagick.processor = :mogrify
7
+
8
+ describe MiniMagick::CommandBuilder do
9
+ before do
10
+ @processor = MiniMagick.processor
11
+ @processor_path = MiniMagick.processor_path
12
+ end
13
+
14
+ after do
15
+ MiniMagick.processor_path = @processor_path
16
+ MiniMagick.processor = @processor
17
+ end
18
+
19
+ describe 'ported from testunit', :ported => true do
20
+ let(:builder) { described_class.new('test') }
21
+
22
+ it 'builds a basic command' do
23
+ builder.resize '30x40'
24
+ expect(builder.args.join(' ')).to eq '-resize 30x40'
25
+ end
26
+
27
+ it 'builds a full command' do
28
+ builder.resize '30x40'
29
+ expect(builder.command).to eq 'test -resize 30x40'
30
+ end
31
+
32
+ describe 'windows only', :if => MiniMagick::Utilities.windows? do
33
+ it 'builds a complicated command' do
34
+ builder.resize '30x40'
35
+ builder.alpha '1 3 4'
36
+ builder.resize 'mome fingo'
37
+ expect(builder.args.join(' ')).to eq '-resize 30x40 -alpha 1 3 4 -resize mome fingo'
38
+ end
39
+
40
+ it 'builds a command with multiple options and plus modifier' do
41
+ builder.distort.+ 'srt', '0.6 20'
42
+ expect(builder.args.join(' ')).to eq '+distort srt 0.6 20'
43
+ end
44
+
45
+ it 'sets a colorspace correctly' do
46
+ builder.set 'colorspace RGB'
47
+ expect(builder.command).to eq 'test -set colorspace RGB'
48
+ end
49
+ end
50
+
51
+ describe 'not windows', :if => !MiniMagick::Utilities.windows? do
52
+ it 'builds a complicated command' do
53
+ builder.resize '30x40'
54
+ builder.alpha '1 3 4'
55
+ builder.resize 'mome fingo'
56
+ expect(builder.args.join(' ')).to eq '-resize 30x40 -alpha 1\ 3\ 4 -resize mome\ fingo'
57
+ end
58
+
59
+ it 'sets a colorspace correctly' do
60
+ builder.set 'colorspace RGB'
61
+ expect(builder.command).to eq 'test -set colorspace\ RGB'
62
+ end
63
+
64
+ it 'builds a command with multiple options and plus modifier' do
65
+ builder.distort.+ 'srt', '0.6 20'
66
+ expect(builder.args.join(' ')).to eq '\+distort srt 0.6\ 20'
67
+ end
68
+ end
69
+
70
+ describe 'common verbs between morgify and image creation operators' do
71
+ context 'mogrify' do
72
+ let(:builder) { described_class.new('mogrify') }
73
+
74
+ it 'builds the command' do
75
+ builder.caption 'caption_text'
76
+ expect(builder.command).to eq 'mogrify -caption caption_text'
77
+ end
78
+ end
79
+
80
+ context 'other' do
81
+ it 'builds the command' do
82
+ builder.caption 'caption_text'
83
+ expect(builder.command).to eq 'test caption:caption_text'
84
+ end
85
+ end
86
+ end
87
+
88
+ it 'raises error when command is invalid' do
89
+ expect {
90
+ command = described_class.new('test', 'path')
91
+ command.input 2
92
+ }.to raise_error
93
+ end
94
+
95
+ it 'builds a dashed command' do
96
+ builder.auto_orient
97
+ expect(builder.args.join(' ')).to eq '-auto-orient'
98
+ end
99
+
100
+ it 'builds a dashed command via send' do
101
+ builder.send('auto-orient')
102
+ expect(builder.args.join(' ')).to eq '-auto-orient'
103
+ end
104
+
105
+ it 'builds a canvas command' do
106
+ builder.canvas 'black'
107
+ expect(builder.args.join(' ')).to eq 'canvas:black'
108
+ end
109
+
110
+ it 'sets a processor path correctly' do
111
+ MiniMagick.processor_path = '/a/strange/path'
112
+ builder.auto_orient
113
+ expect(builder.command).to eq '/a/strange/path/test -auto-orient'
114
+ end
115
+
116
+ it 'builds a processor path with processor' do
117
+ MiniMagick.processor_path = '/a/strange/path'
118
+ MiniMagick.processor = 'processor'
119
+ builder.auto_orient
120
+ expect(builder.command).to eq '/a/strange/path/processor test -auto-orient'
121
+ end
122
+ end
123
+
124
+ describe 'deprecated' do
125
+ let(:builder) { described_class.new('test') }
126
+ before { MiniMagick.processor = nil }
127
+
128
+ it 'builds a full command' do
129
+ builder.resize '30x40'
130
+ expect(builder.command).to eq 'test -resize 30x40'
131
+ end
132
+
133
+ context 'windows only', :if => MiniMagick::Utilities.windows? do
134
+ it 'sets a colorspace correctly' do
135
+ builder.set 'colorspace RGB'
136
+ expect(builder.command).to eq 'test -set colorspace RGB'
137
+ end
138
+ end
139
+
140
+ context 'not windows', :if => !MiniMagick::Utilities.windows? do
141
+ it 'sets a colorspace correctly' do
142
+ builder.set 'colorspace RGB'
143
+ expect(builder.command).to eq 'test -set colorspace\ RGB'
144
+ end
145
+ end
146
+
147
+ it 'sets a processor path correctly' do
148
+ MiniMagick.processor_path = '/a/strange/path'
149
+ builder.auto_orient
150
+ expect(builder.command).to eq '/a/strange/path/test -auto-orient'
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,499 @@
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